History

scripts: add x86 register parser to markup_oops.pl

An oops dump also contains the register values. This patch parses these for (32 bit) x86, and then annotates the disassembly with these values; this helps in analysis of the oops by the developer, for example, NULL pointer or other pointer bugs show up clearly this way.

Arjan van de Ven committed 17 years ago

Commit c19ef7f1 parent 5123b321 file · +100 −6Browse files

Showing the changes to scripts (1 of 1 file). Show all

Unified · Split

scripts/markup_oops.pl+100−6
@@ -32,6 +32,78 @@ my $module = ""; · 31 unmodified lines
3232 my $func_offset;
3333 my $vmaoffset = 0;
3434
35+my %regs;
36+
37+
38+sub parse_x86_regs
39+{
40+ my ($line) = @_;
41+ if ($line =~ /EAX: ([0-9a-f]+) EBX: ([0-9a-f]+) ECX: ([0-9a-f]+) EDX: ([0-9a-f]+)/) {
42+ $regs{"%eax"} = $1;
43+ $regs{"%ebx"} = $2;
44+ $regs{"%ecx"} = $3;
45+ $regs{"%edx"} = $4;
46+ }
47+ if ($line =~ /ESI: ([0-9a-f]+) EDI: ([0-9a-f]+) EBP: ([0-9a-f]+) ESP: ([0-9a-f]+)/) {
48+ $regs{"%esi"} = $1;
49+ $regs{"%edi"} = $2;
50+ $regs{"%esp"} = $4;
51+ }
52+}
53+
54+sub process_x86_regs
55+{
56+ my ($line, $cntr) = @_;
57+ my $str = "";
58+ if (length($line) < 40) {
59+ return ""; # not an asm istruction
60+ }
61+
62+ # find the arguments to the instruction
63+ if ($line =~ /([0-9a-zA-Z\,\%\(\)\-\+]+)$/) {
64+ $lastword = $1;
65+ } else {
66+ return "";
67+ }
68+
69+ # we need to find the registers that get clobbered,
70+ # since their value is no longer relevant for previous
71+ # instructions in the stream.
72+
73+ $clobber = $lastword;
74+ # first, remove all memory operands, they're read only
75+ $clobber =~ s/\([a-z0-9\%\,]+\)//g;
76+ # then, remove everything before the comma, thats the read part
77+ $clobber =~ s/.*\,//g;
78+
79+ # if this is the instruction that faulted, we haven't actually done
80+ # the write yet... nothing is clobbered.
81+ if ($cntr == 0) {
82+ $clobber = "";
83+ }
84+
85+ foreach $reg (keys(%regs)) {
86+ my $val = $regs{$reg};
87+ # first check if we're clobbering this register; if we do
88+ # we print it with a =>, and then delete its value
89+ if ($clobber =~ /$reg/) {
90+ if (length($val) > 0) {
91+ $str = $str . " $reg => $val ";
92+ }
93+ $regs{$reg} = "";
94+ $val = "";
95+ }
96+ # now check if we're reading this register
97+ if ($lastword =~ /$reg/) {
98+ if (length($val) > 0) {
99+ $str = $str . " $reg = $val ";
100+ }
101+ }
102+ }
103+ return $str;
104+}
105+
106+# parse the oops
35107 while (<STDIN>) {
36108 my $line = $_;
37109 if ($line =~ /EIP: 0060:\[\<([a-z0-9]+)\>\]/) {
@@ -46,10 +118,11 @@ while (<STDIN>) { · 8 unmodified lines
46118 if ($line =~ /EIP is at ([a-zA-Z0-9\_]+)\+(0x[0-9a-f]+)\/0x[a-f0-9]+\W\[([a-zA-Z0-9\_\-]+)\]/) {
47119 $module = $3;
48120 }
121+ parse_x86_regs($line);
49122 }
50123
51124 my $decodestart = hex($target) - hex($func_offset);
52−my $decodestop = $decodestart + 8192;
125+my $decodestop = hex($target) + 8192;
53126 if ($target eq "0") {
54127 print "No oops found!\n";
55128 print "Usage: \n";
@@ -84,6 +157,7 @@ my $counter = 0; · 28 unmodified lines
84157 my $state = 0;
85158 my $center = 0;
86159 my @lines;
160+my @reglines;
87161
88162 sub InRange {
89163 my ($address, $target) = @_;
@@ -188,16 +262,36 @@ while ($finish < $counter) { · 98 unmodified lines
188262
189263 my $i;
190264
191−my $fulltext = "";
265+
266+# start annotating the registers in the asm.
267+# this goes from the oopsing point back, so that the annotator
268+# can track (opportunistically) which registers got written and
269+# whos value no longer is relevant.
270+
271+$i = $center;
272+while ($i >= $start) {
273+ $reglines[$i] = process_x86_regs($lines[$i], $center - $i);
274+ $i = $i - 1;
275+}
276+
192277 $i = $start;
193278 while ($i < $finish) {
279+ my $line;
194280 if ($i == $center) {
195− $fulltext = $fulltext . "*$lines[$i] <----- faulting instruction\n";
281+ $line = "*$lines[$i] ";
196282 } else {
197− $fulltext = $fulltext . " $lines[$i]\n";
283+ $line = " $lines[$i] ";
284+ }
285+ print $line;
286+ if (defined($reglines[$i]) && length($reglines[$i]) > 0) {
287+ my $c = 60 - length($line);
288+ while ($c > 0) { print " "; $c = $c - 1; };
289+ print "| $reglines[$i]";
198290 }
291+ if ($i == $center) {
292+ print "<--- faulting instruction";
293+ }
294+ print "\n";
199295 $i = $i +1;
200296 }
201297
202−print $fulltext;
203−