Commit d32ad102 authored by Arjan van de Ven's avatar Arjan van de Ven Committed by Linus Torvalds

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: default avatarArjan van de Ven <arjan@linux.intel.com>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 7df52316
#!/usr/bin/perl -w #!/usr/bin/perl -w
use File::Basename;
# Copyright 2008, Intel Corporation # Copyright 2008, Intel Corporation
# #
# This file is part of the Linux kernel # This file is part of the Linux kernel
...@@ -13,23 +15,41 @@ ...@@ -13,23 +15,41 @@
my $vmlinux_name = $ARGV[0]; my $vmlinux_name = $ARGV[0];
if (!defined($vmlinux_name)) {
my $kerver = `uname -r`;
chomp($kerver);
$vmlinux_name = "/lib/modules/$kerver/build/vmlinux";
print "No vmlinux specified, assuming $vmlinux_name\n";
}
my $filename = $vmlinux_name;
# #
# Step 1: Parse the oops to find the EIP value # Step 1: Parse the oops to find the EIP value
# #
my $target = "0"; my $target = "0";
my $function;
my $module = "";
my $func_offset;
my $vmaoffset = 0;
while (<STDIN>) { while (<STDIN>) {
if ($_ =~ /EIP: 0060:\[\<([a-z0-9]+)\>\]/) { my $line = $_;
if ($line =~ /EIP: 0060:\[\<([a-z0-9]+)\>\]/) {
$target = $1; $target = $1;
} }
} if ($line =~ /EIP is at ([a-zA-Z0-9\_]+)\+(0x[0-9a-f]+)\/0x[a-f0-9]/) {
$function = $1;
$func_offset = $2;
}
if ($target =~ /^f8/) { # check if it's a module
print "This script does not work on modules ... \n"; if ($line =~ /EIP is at ([a-zA-Z0-9\_]+)\+(0x[0-9a-f]+)\/0x[a-f0-9]+\W\[([a-zA-Z0-9\_\-]+)\]/) {
exit; $module = $3;
}
} }
my $decodestart = hex($target) - hex($func_offset);
my $decodestop = $decodestart + 8192;
if ($target eq "0") { if ($target eq "0") {
print "No oops found!\n"; print "No oops found!\n";
print "Usage: \n"; print "Usage: \n";
...@@ -37,6 +57,29 @@ if ($target eq "0") { ...@@ -37,6 +57,29 @@ if ($target eq "0") {
exit; exit;
} }
# if it's a module, we need to find the .ko file and calculate a load offset
if ($module ne "") {
my $dir = dirname($filename);
$dir = $dir . "/";
my $mod = $module . ".ko";
my $modulefile = `find $dir -name $mod | head -1`;
chomp($modulefile);
$filename = $modulefile;
if ($filename eq "") {
print "Module .ko file for $module not found. Aborting\n";
exit;
}
# ok so we found the module, now we need to calculate the vma offset
open(FILE, "objdump -dS $filename |") || die "Cannot start objdump";
while (<FILE>) {
if ($_ =~ /^([0-9a-f]+) \<$function\>\:/) {
my $fu = $1;
$vmaoffset = hex($target) - hex($fu) - hex($func_offset);
}
}
close(FILE);
}
my $counter = 0; my $counter = 0;
my $state = 0; my $state = 0;
my $center = 0; my $center = 0;
...@@ -59,9 +102,7 @@ sub InRange { ...@@ -59,9 +102,7 @@ sub InRange {
# first, parse the input into the lines array, but to keep size down, # first, parse the input into the lines array, but to keep size down,
# we only do this for 4Kb around the sweet spot # we only do this for 4Kb around the sweet spot
my $filename; open(FILE, "objdump -dS --adjust-vma=$vmaoffset --start-address=$decodestart --stop-address=$decodestop $filename |") || die "Cannot start objdump";
open(FILE, "objdump -dS $vmlinux_name |") || die "Cannot start objdump";
while (<FILE>) { while (<FILE>) {
my $line = $_; my $line = $_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment