Commit d32ad102c6d748b510fd89f1af4232eac1be8732

Authored by Arjan van de Ven
Committed by Linus Torvalds
1 parent 7df5231660

script: improve markup_oops.pl to also decode oopses in modules

There has been some light flamewar on lkml about decoding oopses
in modules (as part of the crashdump flamewar).

Now this isn't rocket science, just the markup_oops.pl script
cheaped out and didn't handle modules. But really; a flamewar
all about that?? What happened to C++ in the kernel or reading
files from inside the kernel?

This patch adds module support to markup_oops.pl; it's not the
most pretty perl but it works for my testcases...

Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 1 changed file with 50 additions and 9 deletions Side-by-side Diff

scripts/markup_oops.pl
1 1 #!/usr/bin/perl -w
2 2  
  3 +use File::Basename;
  4 +
3 5 # Copyright 2008, Intel Corporation
4 6 #
5 7 # This file is part of the Linux kernel
6 8  
7 9  
8 10  
9 11  
10 12  
... ... @@ -13,23 +15,41 @@
13 15  
14 16  
15 17 my $vmlinux_name = $ARGV[0];
16   -
  18 +if (!defined($vmlinux_name)) {
  19 + my $kerver = `uname -r`;
  20 + chomp($kerver);
  21 + $vmlinux_name = "/lib/modules/$kerver/build/vmlinux";
  22 + print "No vmlinux specified, assuming $vmlinux_name\n";
  23 +}
  24 +my $filename = $vmlinux_name;
17 25 #
18 26 # Step 1: Parse the oops to find the EIP value
19 27 #
20 28  
21 29 my $target = "0";
  30 +my $function;
  31 +my $module = "";
  32 +my $func_offset;
  33 +my $vmaoffset = 0;
  34 +
22 35 while (<STDIN>) {
23   - if ($_ =~ /EIP: 0060:\[\<([a-z0-9]+)\>\]/) {
  36 + my $line = $_;
  37 + if ($line =~ /EIP: 0060:\[\<([a-z0-9]+)\>\]/) {
24 38 $target = $1;
25 39 }
26   -}
  40 + if ($line =~ /EIP is at ([a-zA-Z0-9\_]+)\+(0x[0-9a-f]+)\/0x[a-f0-9]/) {
  41 + $function = $1;
  42 + $func_offset = $2;
  43 + }
27 44  
28   -if ($target =~ /^f8/) {
29   - print "This script does not work on modules ... \n";
30   - exit;
  45 + # check if it's a module
  46 + 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;
  48 + }
31 49 }
32 50  
  51 +my $decodestart = hex($target) - hex($func_offset);
  52 +my $decodestop = $decodestart + 8192;
33 53 if ($target eq "0") {
34 54 print "No oops found!\n";
35 55 print "Usage: \n";
... ... @@ -37,6 +57,29 @@
37 57 exit;
38 58 }
39 59  
  60 +# if it's a module, we need to find the .ko file and calculate a load offset
  61 +if ($module ne "") {
  62 + my $dir = dirname($filename);
  63 + $dir = $dir . "/";
  64 + my $mod = $module . ".ko";
  65 + my $modulefile = `find $dir -name $mod | head -1`;
  66 + chomp($modulefile);
  67 + $filename = $modulefile;
  68 + if ($filename eq "") {
  69 + print "Module .ko file for $module not found. Aborting\n";
  70 + exit;
  71 + }
  72 + # ok so we found the module, now we need to calculate the vma offset
  73 + open(FILE, "objdump -dS $filename |") || die "Cannot start objdump";
  74 + while (<FILE>) {
  75 + if ($_ =~ /^([0-9a-f]+) \<$function\>\:/) {
  76 + my $fu = $1;
  77 + $vmaoffset = hex($target) - hex($fu) - hex($func_offset);
  78 + }
  79 + }
  80 + close(FILE);
  81 +}
  82 +
40 83 my $counter = 0;
41 84 my $state = 0;
42 85 my $center = 0;
... ... @@ -59,9 +102,7 @@
59 102 # first, parse the input into the lines array, but to keep size down,
60 103 # we only do this for 4Kb around the sweet spot
61 104  
62   -my $filename;
63   -
64   -open(FILE, "objdump -dS $vmlinux_name |") || die "Cannot start objdump";
  105 +open(FILE, "objdump -dS --adjust-vma=$vmaoffset --start-address=$decodestart --stop-address=$decodestop $filename |") || die "Cannot start objdump";
65 106  
66 107 while (<FILE>) {
67 108 my $line = $_;