From: Alan Stebbens <aks%anywhere@hub.ucsb.edu>
Subject: "panicanal": vmunix panic analyzer
Reply-To: aks%anywhere@hub.ucsb.edu
Organization: The Internet
Date: Wed, 2 Sep 1992 20:18:03 GMT

The following is a first-cut attempt Perl script at parsing panic dump
output.  The script accepts a filename argument, defaulting to
/var/adm/messages, and scans the file for "vmunix: panic:" messages.  If
there is any subsequent traceback listing, they are listed along with
the symbolic addresses and instructions at those locations using adb
queries on the kernel code.

A really clever script would even attempt to parse the arg lists and
show the values at the corresponding addresses, but this script isn't
that one (yet).

Enjoy.

Alan Stebbens        <aks@hub.ucsb.edu>             (805) 893-3221
     Center for Computational Sciences and Engineering (CCSE)
          University of California, Santa Barbara (UCSB)
           3111 Engineering I, Santa Barbara, CA 93106

============================= cut here ===================================
#!/bin/perl -s
# panicanal [-i] [file]
#
# $Revision: 1.2 $ $Date: 1992/09/02 19:06:10 $
# Alan K. Stebbens <aks@hub.ucsb.edu>, CCSE, UCSB
#
# Do analysis of vmunix panic's as written in file (default is
# /var/adm/messages).
#
# If -a given, do all dumps, otherwise, interact with the user
# If STDOUT is not a tty, assume -a.
#
$all = $a unless $all;
$dumpfile = '/var/adm/messages' unless $dumpfile = shift;
die "$dumpfile doesn't exist" unless -f $dumpfile;

$interact = $all ? '' : -t;

open(DUMP,$dumpfile) || die "Can't read $dumpfile because $!\n";
$defans = 'n';				# initial default answer is 'no'
while (<DUMP>) {
    next unless /vmunix: panic:/;
    chop;
    ($mon, $day, $time, $host, $what) = split(' ');
    $thispanic = $1 if s/^(.* vmunix: )//;# strip leader
    $what = $1 if /panic: (.*)/;
    @panic = ($_);			 # start saving the panic
    $begin = 0;
    while (<DUMP>) {
	last unless s/^$thispanic//;	# quit when no more data
	$begin++ if /Begin traceback\.\.\./;
	chop;
	push(@panic,$_);		# add to panic data
	last if /End traceback\.\.\./;
    }
    next unless $begin;			# don't analyze without a traceback
    if ($interact) {			# talk to user?
	print "\nPanic: \"$what\" on $mon $day at $time, analyze (ynq)? [$defans]";
	exit unless $ans = <STDIN>;
	chop($ans);
	$ans = $defans unless $ans;
	$defans = $ans;			# new default
	exit     if !index('quit',$ans);
	next unless !index('yes',$ans);
    }
    &analyze;
}
close DUMP;
exit;

sub analyze {
    local($_);

    $addr = '';
    $tmp = "/tmp/$$.anal";
    open(TMP,">$tmp") || die "Can't open $tmp because $!\n";
    @addrs = ();
    foreach (@panic) {
	printf "%s\n",$_;
	next unless /Called from ([0-9a-f]+),/ || /pc=0x([0-9a-f]+),/;
	$addr = $1;
	print TMP "$addr?i\n";
	push(@addrs,$addr);
    }
    close TMP;
    open(ADB,"adb /vmunix < $tmp|") || die "Can't open pipe from adb because $!\n";
    while (<ADB>) {
	chop;
	next if /^\s*$/;
	$addr = shift @addrs;
	if (!/text address not found/) {
	    ($symaddr,$instr) = ($1,$2) if /^([^:]+:)\s+(.*)/;
	    printf "%s: %-30s %s\n",$addr,$symaddr,$instr;
	}
    }
    close ADB;
    unlink $tmp;
}
Newsgroups: comp.lang.perl