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

Unified · Split

scripts/markup_oops.pl+100−6
@@ -32,6 +32,78 @@ my $module = ""; · 31 unmodified lines
32my $func_offset;32my $func_offset;
33my $vmaoffset = 0;33my $vmaoffset = 0;
34 34
35my %regs;
36
37
38sub 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
54sub 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
35while (<STDIN>) {107while (<STDIN>) {
36 my $line = $_;108 my $line = $_;
37 if ($line =~ /EIP: 0060:\[\<([a-z0-9]+)\>\]/) {109 if ($line =~ /EIP: 0060:\[\<([a-z0-9]+)\>\]/) {
@@ -46,10 +118,11 @@ while (<STDIN>) { · 8 unmodified lines
46 if ($line =~ /EIP is at ([a-zA-Z0-9\_]+)\+(0x[0-9a-f]+)\/0x[a-f0-9]+\W\[([a-zA-Z0-9\_\-]+)\]/) {118 if ($line =~ /EIP is at ([a-zA-Z0-9\_]+)\+(0x[0-9a-f]+)\/0x[a-f0-9]+\W\[([a-zA-Z0-9\_\-]+)\]/) {
47 $module = $3;119 $module = $3;
48 }120 }
121 parse_x86_regs($line);
49}122}
50 123
51my $decodestart = hex($target) - hex($func_offset);124my $decodestart = hex($target) - hex($func_offset);
52my $decodestop = $decodestart + 8192;125my $decodestop = hex($target) + 8192;
53if ($target eq "0") {126if ($target eq "0") {
54 print "No oops found!\n";127 print "No oops found!\n";
55 print "Usage: \n";128 print "Usage: \n";
@@ -84,6 +157,7 @@ my $counter = 0; · 28 unmodified lines
84my $state = 0;157my $state = 0;
85my $center = 0;158my $center = 0;
86my @lines;159my @lines;
160my @reglines;
87 161
88sub InRange {162sub InRange {
89 my ($address, $target) = @_;163 my ($address, $target) = @_;
@@ -188,16 +262,36 @@ while ($finish < $counter) { · 98 unmodified lines
188 262
189my $i;263my $i;
190 264
191my $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;
272while ($i >= $start) {
273 $reglines[$i] = process_x86_regs($lines[$i], $center - $i);
274 $i = $i - 1;
275}
276
192$i = $start;277$i = $start;
193while ($i < $finish) {278while ($i < $finish) {
279 my $line;
194 if ($i == $center) {280 if ($i == $center) {
195 $fulltext = $fulltext . "*$lines[$i] <----- faulting instruction\n";281 $line = "*$lines[$i] ";
196 } else {282 } 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]";
198 }290 }
291 if ($i == $center) {
292 print "<--- faulting instruction";
293 }
294 print "\n";
199 $i = $i +1;295 $i = $i +1;
200}296}
201 297
202print $fulltext;
203