lkml.org 
[lkml]   [2011]   [Aug]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    From
    Date
    SubjectRe: A script that used by GDB to load the symbols from Linux kernel modules
    Add a menu for select directory and a check.

    Thanks,
    Hui

    On Wed, Aug 17, 2011 at 13:45, Hui Zhu <teawater@gmail.com> wrote:
    > Hi,
    >
    > When use GDB to debug or trace your kernel with KGDB, QEMU debug
    > interface or KGTP.  You must get some trouble with LKM symbols.  For
    > example:
    > (gdb) target remote localhost:12345
    > Remote debugging using localhost:12345
    > native_safe_halt () at
    > /home/teawater/big/kernel/linux-2.6/arch/x86/include/asm/irqflags.h:50
    > 50      }
    > (gdb) b e100_poll
    > Function "e100_poll" not defined.
    > Make breakpoint pending on future shared library load? (y or [n])
    > This is because GDB didn't get the LKM symbols.  You can do it with
    > your hand.  But if you have a lot of LKMs, it will need some time.
    >
    > Now, GDB support python script.  The attachment is a script to load
    > all symbols from Linux kernel modules to GDB.
    > For example:
    > (gdb) target remote localhost:12345
    > Remote debugging using localhost:12345
    > native_safe_halt () at
    > /home/teawater/big/kernel/linux-2.6/arch/x86/include/asm/irqflags.h:50
    > 50      }
    > (gdb) so ~/kernel/svn/branches/teawater/getmod.py
    > (gdb) b e100_poll
    > Breakpoint 1 at 0xc889db40: file
    > /home/teawater/big/kernel/linux-2.6/drivers/net/e100.c, line 2165.
    >
    > This script will include in KGTP(https://code.google.com/p/kgtp/) source.
    >
    > Thanks,
    > Hui
    >
    #!/usr/bin/python

    # This script is used by GDB to load the symbols from Linux kernel modules
    # GPL
    # Copyright(C) Hui Zhu (teawater@gmail.com), 2011

    #Set special mod_search_dir
    #set $mod_search_dir="dir"
    #Clear special mod_search_dir
    #set $mod_search_dir=(void)1

    import gdb;
    import os;

    def format_file(name):
    tmp = "";
    for c in name:
    if c == "_":
    c = "-";
    tmp += c;
    return tmp;

    #Check if the target is available
    if str(gdb.selected_thread()) == "None":
    raise gdb.error("Please connect to Linux Kernel before use the script.");

    #Output the help
    print "Use GDB command \"set $mod_search_dir=dir\" to set an directory for search the modules."

    #Get the mod_search_dir
    mod_search_dir_list = [];
    #Get dir from $mod_search_dir
    tmp_dir = gdb.parse_and_eval("$mod_search_dir");
    if tmp_dir.type.code == gdb.TYPE_CODE_ARRAY:
    tmp_dir = str(tmp_dir);
    tmp_dir = tmp_dir[1:len(tmp_dir)];
    tmp_dir = tmp_dir[0:tmp_dir.index("\"")];
    mod_search_dir_list.append(tmp_dir);
    #Get dir that same with current vmlinux
    tmp_dir = str(gdb.execute("info files", False, True));
    tmp_dir = tmp_dir[tmp_dir.index("Symbols from \"")+len("Symbols from \""):len(tmp_dir)];
    tmp_dir = tmp_dir[0:tmp_dir.index("\"")];
    tmp_dir = tmp_dir[0:tmp_dir.rindex("/")];
    mod_search_dir_list.append(tmp_dir);
    #Get the dir of current Kernel
    tmp_dir = "/lib/modules/" + str(os.uname()[2]);
    if os.path.isdir(tmp_dir):
    mod_search_dir_list.append(tmp_dir);
    #Let user choice dir
    mod_search_dir = "";
    while mod_search_dir == "":
    for i in range(0, len(mod_search_dir_list)):
    print str(i)+". "+mod_search_dir_list[i];
    try:
    s = input('Select a directory for search the modules [0]:');
    except SyntaxError:
    s = 0;
    except:
    continue;
    if s < 0 or s >= len(mod_search_dir_list):
    continue;
    mod_search_dir = mod_search_dir_list[i];

    mod_list_offset = long(gdb.parse_and_eval("((size_t) &(((struct module *)0)->list))"));
    mod_list = long(gdb.parse_and_eval("(&modules)"));
    mod_list_current = mod_list;

    while 1:
    mod_list_current = long(gdb.parse_and_eval("((struct list_head *) "+str(mod_list_current)+")->next"));

    #check if need break the loop
    if mod_list == mod_list_current:
    break;

    mod = mod_list_current - mod_list_offset;

    #get mod_name
    mod_name = str(gdb.parse_and_eval("((struct module *)"+str(mod)+")->name"));
    mod_name = mod_name[mod_name.index("\"")+1:len(mod_name)];
    mod_name = mod_name[0:mod_name.index("\"")];
    mod_name += ".ko"
    mod_name = format_file(mod_name);

    #get mod_dir_name
    mod_dir_name = "";
    for root, dirs, files in os.walk(mod_search_dir):
    for afile in files:
    tmp_file = format_file(afile);
    if tmp_file == mod_name:
    mod_dir_name = os.path.join(root,afile);
    break;
    if mod_dir_name != "":
    break;

    command = " ";

    #Add module_core to command
    command += str(gdb.parse_and_eval("((struct module *)"+str(mod)+")->module_core"));

    #Add each sect_attrs->attrs to command
    #get nsections
    nsections = int(gdb.parse_and_eval("((struct module *)"+str(mod)+")->sect_attrs->nsections"));
    sect_attrs = long(gdb.parse_and_eval("(u64)((struct module *)"+str(mod)+")->sect_attrs"));
    for i in range(0, nsections):
    command += " -s";
    tmp = str(gdb.parse_and_eval("((struct module_sect_attrs *)"+str(sect_attrs)+")->attrs["+str(i)+"].name"));
    tmp = tmp[tmp.index("\"")+1:len(tmp)];
    tmp = tmp[0:tmp.index("\"")];
    command += " "+tmp;
    tmp = str(gdb.parse_and_eval("((struct module_sect_attrs *)"+str(sect_attrs)+")->attrs["+str(i)+"].address"));
    command += " "+tmp;

    if mod_dir_name == "":
    print "Can find out",mod_name,"from directory.";
    print "Please use following command load the symbols from it:"
    print "add-symbol-file some_dir/"+mod_name+command;
    else:
    #print "add-symbol-file "+mod_dir_name+command;
    gdb.execute("add-symbol-file "+mod_dir_name+command, False, False);
    \
     
     \ /
      Last update: 2011-08-18 10:27    [W:0.033 / U:4.136 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site