home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #19 / NN_1992_19.iso / spool / comp / lang / perl / 5710 < prev    next >
Encoding:
Text File  |  1992-09-03  |  4.6 KB  |  146 lines

  1. Newsgroups: comp.lang.perl
  2. Path: sparky!uunet!gatech!darwin.sura.net!uvaarpa!mmdf
  3. From: Alan Stebbens <aks%anywhere@hub.ucsb.edu>
  4. Subject: Update on "panicanal": now "traceanal" w/improvements
  5. Message-ID: <1992Sep3.193315.29809@uvaarpa.Virginia.EDU>
  6. Sender: mmdf@uvaarpa.Virginia.EDU (Mail System)
  7. Reply-To: aks%anywhere@hub.ucsb.edu
  8. Organization: The Internet
  9. Date: Thu, 3 Sep 1992 19:33:15 GMT
  10. Lines: 134
  11.  
  12. This is an improvement on the Perl program I sent a few days ago called
  13. "panicanal"; it has been improved since then, and its name has been
  14. changed to better reflect its function: "traceanal".  It looks for
  15. traceback messages in the named file, /var/adm/messages, by default
  16. (stdin is given with a file arg of '-'), and passes the addresses to
  17. "adb" for symbolic decoding against the kernel (/vmunix).  You should
  18. even be able to do: "dmesg | traceanal -"
  19.  
  20. It now supports a "summary" option (-s or -summary), which provides a
  21. summary of the tracebacks found in the file.
  22.  
  23. As you might guess, the motivation for this script to help diagnose an
  24. apparent kernel bug that we are currently experiencing, in the form of
  25. spurious or random faults on one of our sparc1stations.  Not
  26. incidentally, we are running it as a relatively loaded NFS fileserver
  27. with four 1.7GB SCSI drives.  We've totally eliminated the hardware as
  28. being the fault.
  29.  
  30. Enjoy.
  31.  
  32. Alan Stebbens        <aks@hub.ucsb.edu>             (805) 893-3221
  33.      Center for Computational Sciences and Engineering (CCSE)
  34.           University of California, Santa Barbara (UCSB)
  35.            3111 Engineering I, Santa Barbara, CA 93106
  36.  
  37. ============================= cut here ===================================
  38. #!/bin/perl -s
  39. # traceanal [-a] [-s] [file]
  40. #
  41. # $Revision: 1.3 $ $Date: 1992/09/03 18:44:57 $
  42. # Alan K. Stebbens, CCSE, UCSB
  43. #
  44. # Do analysis of vmunix tracebacks as written in file (default is
  45. # /var/adm/messages).
  46. #
  47. # If -a given, do all dumps, otherwise, interact with the user
  48. # If STDOUT is not a tty, assume -a.
  49. #
  50. # If -s given, do a summary of the dumps.
  51. #
  52. $all = $a     unless $all;
  53. $summary = $s unless $summary;
  54.  
  55. $dumpfile = '/var/adm/messages' unless $dumpfile = shift;
  56. die "$dumpfile doesn't exist" unless ($dumpfile eq '-') || -f $dumpfile;
  57.  
  58. $KEEP_LINES = 6;
  59.  
  60. $interact = !($all || $summary) && -t && $dumpfile ne '-';    # set interaction flag
  61.  
  62. open(DUMP,$dumpfile) || die "Can't read $dumpfile because $!\n";
  63. $defans = 'n';                # initial default answer is 'no'
  64. select(STDOUT);
  65. $| = 1;                    # flush all STDOUT
  66. while (<DUMP>) {
  67.     push(@lines,$_);
  68.     shift(@lines) if $#lines > $KEEP_LINES;    # keep only so many lines
  69.     next if !/Begin traceback\.\.\./;    # loop until the traceback starts
  70.     $header = $1 if /^(.*)Begin traceback\.\.\./;
  71.     @lines = grep(s/$header//,@lines);    # remove the headers
  72.     @lines = grep(chop($_),@lines);    # remove the newlines
  73.     $what = '';
  74.     $pidinfo = '';
  75.     foreach (@lines) {            # look for the reason
  76.     if (!$what) {
  77.         $what = $1 if /^panic:\s*(\S.*)/ || 
  78.               /^([A-Z -]+)/ || 
  79.               /^syncing file systems\.+[ \d]*([A-Z -]+)/;
  80.     }
  81.     if (!$pidinfo) {
  82.         $pidinfo = $1 if /^(pid \d+,.*)/;
  83.     }
  84.     last if $what && $pidinfo;    # quit when both found
  85.     }
  86.     $mon = '';
  87.     ($mon, $day, $time, $host, $proc) = split(' ',$header) if $header;
  88.     @trace = @lines;            # setup the trace data
  89.     @lines = ();
  90.     while (<DUMP>) {
  91.     chop;
  92.     last unless s/$header//;    # strip header
  93.     push(@trace,$_);        # add to trace data
  94.     last if /End traceback\.\.\./;
  95.     }
  96.     printf "\n" unless $summary;
  97.     printf "Traceback";
  98.     printf " on $mon $day at $time" if $mon;
  99.     printf " on $host" if $host;
  100.     $pidinfo =~ s/: $what//;        # avoid duplicate stuff
  101.     printf " : $what, $pidinfo" if $summary || $interact;
  102.     printf "\n";
  103.     if ($interact) {
  104.     printf "Analyze (ynq)? [$defans]";
  105.     exit unless $ans = <STDIN>;
  106.     chop($ans);
  107.     $ans = $defans unless $ans;
  108.     $defans = $ans;            # new default
  109.     exit     if !index('quit',$ans);
  110.     next unless !index('yes',$ans);
  111.     }
  112.     &analyze unless $summary;
  113. }
  114. close DUMP;
  115. exit;
  116.  
  117. sub analyze {
  118.     local($_);
  119.  
  120.     $addr = '';
  121.     $tmp = "/tmp/$$.anal";
  122.     open(TMP,">$tmp") || die "Can't open $tmp because $!\n";
  123.     @addrs = ();
  124.     foreach (@trace) {
  125.     printf "%s\n",$_;
  126.     next unless /Called from ([0-9a-f]+),/ || /pc=0x([0-9a-f]+),/;
  127.     $addr = $1;
  128.     print TMP "$addr?i\n";
  129.     push(@addrs,$addr);
  130.     }
  131.     close TMP;
  132.     $| = 1;            # flush STDOUT
  133.     open(ADB,"adb /vmunix < $tmp|") || die "Can't open pipe from adb because $!\n";
  134.     while (<ADB>) {
  135.     chop;
  136.     next if /^\s*$/;
  137.     $addr = shift @addrs;
  138.     if (!/text address not found/) {
  139.         ($symaddr,$instr) = ($1,$2) if /^([^:]+:)\s+(.*)/;
  140.         printf "%s: %-30s %s\n",$addr,$symaddr,$instr;
  141.     }
  142.     }
  143.     close ADB;
  144.     unlink $tmp;
  145. }
  146.