[PATCH] scripts: script from kerneloops.org to pretty print oops dumps - Kernel

This is a discussion on [PATCH] scripts: script from kerneloops.org to pretty print oops dumps - Kernel ; Hi, I had this script lying around (used on kerneloops.org in a slightly modified form, where I use a database as input rather than stdin). I think it's a useful tool, at least I find it extremely useful in turning ...

+ Reply to Thread
Results 1 to 4 of 4

Thread: [PATCH] scripts: script from kerneloops.org to pretty print oops dumps

  1. [PATCH] scripts: script from kerneloops.org to pretty print oops dumps

    Hi,

    I had this script lying around (used on kerneloops.org in a slightly modified form,
    where I use a database as input rather than stdin). I think it's a useful tool,
    at least I find it extremely useful in turning oopses into an "oh duh yes there"
    experience...

    I know it's in perl, and I know I suck at writing good perl. So I welcome all feedback I
    can get... both on the perl and on the usefulness of having this script.


    From 260d3f2246a4fe92f4ec633db82ab44605654d4f Mon Sep 17 00:00:00 2001
    From: Arjan van de Ven
    Date: Wed, 5 Nov 2008 19:00:36 -0800
    Subject: [PATCH] scripts: script from kerneloops.org to pretty print oops dumps

    We're strugling all the time to figure out where the code came from
    that oopsed.. The script below (a adaption from a script used by kerneloops.org)
    can help developers quite a bit, at least for non-module cases.

    It works and looks like this:

    [/home/arjan/linux]$ dmesg | perl scripts/markup_code.pl vmlinux
    {
    struct agp_memory *memory;

    memory = agp_allocate_memory(agp_bridge, pg_count, type);
    c055c10f: 89 c2 mov %eax,%edx
    if (memory == NULL)
    c055c111: 74 19 je c055c12c
    /* This function must only be called when current_controller != NULL */
    static void agp_insert_into_pool(struct agp_memory * temp)
    {
    struct agp_memory *prev;

    prev = agp_fe.current_controller->pool;
    c055c113: a1 ec dc 8f c0 mov 0xc08fdcec,%eax
    *c055c118: 8b 40 10 mov 0x10(%eax),%eax <----- faulting instruction

    if (prev != NULL) {
    c055c11b: 85 c0 test %eax,%eax
    c055c11d: 74 05 je c055c124
    prev->prev = temp;
    c055c11f: 89 50 04 mov %edx,0x4(%eax)
    temp->next = prev;
    c055c122: 89 02 mov %eax,(%edx)
    }
    agp_fe.current_controller->pool = temp;
    c055c124: a1 ec dc 8f c0 mov 0xc08fdcec,%eax
    c055c129: 89 50 10 mov %edx,0x10(%eax)
    if (memory == NULL)
    return NULL;

    agp_insert_into_pool(memory);

    so in this case, we faulted while dereferencing agp_fe.current_controller pointer, and we get to see
    exactly which function and line it affects... Personally I find this very useful, and I can
    see value for having this script in the kernel for more-than-just-me to use.

    Caveats:
    * It only works for oopses not-in-modules
    * It only works nicely for kernels compiled with CONFIG_DEBUG_INFO
    * It's not very fast.

    Signed-off-by: Arjan van de Ven
    ---
    scripts/markup_oops.pl | 165 ++++++++++++++++++++++++++++++++++++++++++++++++
    1 files changed, 165 insertions(+), 0 deletions(-)
    create mode 100644 scripts/markup_oops.pl

    diff --git a/scripts/markup_oops.pl b/scripts/markup_oops.pl
    new file mode 100644
    index 0000000..c8a2200
    --- /dev/null
    +++ b/scripts/markup_oops.pl
    @@ -0,0 +1,165 @@
    +#!/usr/bin/perl -w
    +
    +# Copyright 2008, Intel Corporation
    +#
    +# This file is part of the Linux kernel
    +#
    +# This program file is free software; you can redistribute it and/or modify it
    +# under the terms of the GNU General Public License as published by the
    +# Free Software Foundation; version 2 of the License.
    +#
    +# Authors:
    +# Arjan van de Ven
    +
    +
    +my $vmlinux_name = $ARGV[0];
    +
    +#
    +# Step 1: Parse the oops to find the EIP value
    +#
    +
    +my $target = "0";
    +while () {
    + if ($_ =~ /EIP: 0060:\[\<([a-z0-9]+)\>\]/) {
    + $target = $1;
    + }
    +}
    +
    +if ($target =~ /^f8/) {
    + print "This script does not work on modules ... \n";
    + exit;
    +}
    +
    +if ($target eq "0") {
    + print "No oops found!\n";
    + print "Usage: \n";
    + print " dmesg | perl scripts/markup_oops.pl vmlinux\n";
    + exit;
    +}
    +
    +my $counter = 0;
    +my $state = 0;
    +my $center = 0;
    +my @lines;
    +
    +sub InRange {
    + my ($address, $target) = @_;
    + my $ad = "0x".$address;
    + my $ta = "0x".$target;
    + my $delta = hex($ad) - hex($ta);
    +
    + if (($delta > -4096) && ($delta < 4096)) {
    + return 1;
    + }
    + return 0;
    +}
    +
    +
    +
    +# first, parse the input into the lines array, but to keep size down,
    +# we only do this for 4Kb around the sweet spot
    +
    +my $filename;
    +
    +open(FILE, "objdump -dS $vmlinux_name |") || die "Cannot start objdump";
    +
    +while () {
    + my $line = $_;
    + chomp($line);
    + if ($state == 0) {
    + if ($line =~ /^([a-f0-9]+)\:/) {
    + if (InRange($1, $target)) {
    + $state = 1;
    + }
    + }
    + } else {
    + if ($line =~ /^([a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9]+)\:/) {
    + my $val = $1;
    + if (!InRange($val, $target)) {
    + last;
    + }
    + if ($val eq $target) {
    + $center = $counter;
    + }
    + }
    + $lines[$counter] = $line;
    +
    + $counter = $counter + 1;
    + }
    +}
    +
    +close(FILE);
    +
    +if ($counter == 0) {
    + print "No matching code found \n";
    + exit;
    +}
    +
    +if ($center == 0) {
    + print "No matching code found \n";
    + exit;
    +}
    +
    +my $start;
    +my $finish;
    +my $codelines;
    +my $binarylines;
    +# now we go up and down in the array to find how much we want to print
    +
    +$start = $center;
    +$codelines = 0;
    +$binarylines = 0;
    +while ($start > 1) {
    + $start = $start - 1;
    + my $line = $lines[$start];
    + if ($line =~ /^([a-f0-9]+)\:/) {
    + $binarylines = $binarylines + 1;
    + } else {
    + $codelines = $codelines + 1;
    + }
    + if ($codelines > 10) {
    + last;
    + }
    + if ($binarylines > 20) {
    + last;
    + }
    +}
    +
    +
    +$finish = $center;
    +$codelines = 0;
    +$binarylines = 0;
    +while ($finish < $counter) {
    + $finish = $finish + 1;
    + my $line = $lines[$finish];
    + if ($line =~ /^([a-f0-9]+)\:/) {
    + $binarylines = $binarylines + 1;
    + } else {
    + $codelines = $codelines + 1;
    + }
    + if ($codelines > 10) {
    + last;
    + }
    + if ($binarylines > 20) {
    + last;
    + }
    +}
    +
    +
    +my $i;
    +
    +my $fulltext = "";
    +$i = $start;
    +while ($i < $finish) {
    + if ($i == $center) {
    + $fulltext = $fulltext . "*$lines[$i] <----- faulting instruction\n";
    + } else {
    + $fulltext = $fulltext . " $lines[$i]\n";
    + }
    + $i = $i +1;
    +}
    +
    +
    +
    +print $fulltext;
    +
    --
    1.6.0.3



    --
    Arjan van de Ven Intel Open Source Technology Centre
    For development, discussion and tips for power savings,
    visit http://www.lesswatts.org
    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  2. Re: [PATCH] scripts: script from kerneloops.org to pretty print oops dumps

    Arjan van de Ven (on Wed, 5 Nov 2008 19:07:26 -0800) wrote:
    >I had this script lying around (used on kerneloops.org in a slightly modified form,
    >where I use a database as input rather than stdin). I think it's a useful tool,
    >at least I find it extremely useful in turning oopses into an "oh duh yes there"
    >experience...
    >
    >Caveats:
    >* It only works for oopses not-in-modules
    >* It only works nicely for kernels compiled with CONFIG_DEBUG_INFO
    >* It's not very fast.


    Another caveat: "if ($_ =~ /EIP: 0060:\[\<([a-z0-9]+)\>\]/)" means that
    it only works on x86_32.

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  3. Re: [PATCH] scripts: script from kerneloops.org to pretty print oops dumps

    On Thu, 06 Nov 2008 15:15:22 +1100
    Keith Owens wrote:

    > Arjan van de Ven (on Wed, 5 Nov 2008 19:07:26 -0800) wrote:
    > >I had this script lying around (used on kerneloops.org in a slightly
    > >modified form, where I use a database as input rather than stdin). I
    > >think it's a useful tool, at least I find it extremely useful in
    > >turning oopses into an "oh duh yes there" experience...
    > >
    > >Caveats:
    > >* It only works for oopses not-in-modules
    > >* It only works nicely for kernels compiled with CONFIG_DEBUG_INFO
    > >* It's not very fast.

    >
    > Another caveat: "if ($_ =~ /EIP: 0060:\[\<([a-z0-9]+)\>\]/)" means
    > that it only works on x86_32.
    >


    true. I've not tried it/adapted it on any other arch yet.


    --
    Arjan van de Ven Intel Open Source Technology Centre
    For development, discussion and tips for power savings,
    visit http://www.lesswatts.org
    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  4. Re: [PATCH] scripts: script from kerneloops.org to pretty print oops dumps

    On Wed, Nov 05, 2008 at 07:07:26PM -0800, Arjan van de Ven wrote:
    >Hi,
    >


    Hi,

    thanks for your work!

    >
    >diff --git a/scripts/markup_oops.pl b/scripts/markup_oops.pl
    >new file mode 100644
    >index 0000000..c8a2200
    >--- /dev/null
    >+++ b/scripts/markup_oops.pl
    >@@ -0,0 +1,165 @@
    >+#!/usr/bin/perl -w
    >+
    >+# Copyright 2008, Intel Corporation
    >+#
    >+# This file is part of the Linux kernel
    >+#
    >+# This program file is free software; you can redistribute it and/or modify it
    >+# under the terms of the GNU General Public License as published by the
    >+# Free Software Foundation; version 2 of the License.
    >+#
    >+# Authors:
    >+# Arjan van de Ven
    >+
    >+
    >+my $vmlinux_name = $ARGV[0];
    >+
    >+#
    >+# Step 1: Parse the oops to find the EIP value
    >+#
    >+
    >+my $target = "0";
    >+while () {
    >+ if ($_ =~ /EIP: 0060:\[\<([a-z0-9]+)\>\]/) {
    >+ $target = $1;
    >+ }
    >+}
    >+
    >+if ($target =~ /^f8/) {
    >+ print "This script does not work on modules ... \n";
    >+ exit;
    >+}
    >+
    >+if ($target eq "0") {
    >+ print "No oops found!\n";
    >+ print "Usage: \n";
    >+ print " dmesg | perl scripts/markup_oops.pl vmlinux\n";
    >+ exit;



    One thing to note here, no oops doesn't always mean wrong usage.
    So I think usage should be printed only when the usage is actually
    wrong, e.g. ARGV[0] is missed.



    >+$start = $center;
    >+$codelines = 0;
    >+$binarylines = 0;


    Why not fold these lines into their definitions?


    --
    "Sometimes the only way to stay sane is to go a little crazy."

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

+ Reply to Thread