内核调试

 

  1. 让内核启动时的调试信息能过串口输出

  2. 目标机: 打开/boot/grub/grub.conf

    加入

    title Red Flag Desktop (2.6.32.8) root (hd0,0) kernel /boot/vmlinuz-2.6.32.8 ro root=LABEL=/ vga=788 splash=silent resume=/dev/sda2 console=ttyS0,115200 console=tty0   

     (console=ttyS0,115200指控制台重定位到串口一,并设置速率为115200)

     initrd /boot/initrd-2.6.32.8.img

     

    开发机:

    设置串口:

    [root@localhost boot]# stty ispeed 115200 ospeed 115200 -F /dev/ttyS0

    接收数据:

    [root@localhost boot]# cat /dev/ttyS0

     

     

  3. 用KGDB远程调试 内核:

  4. 原理:

     

    内核配置:

     

    General setup

        --> Prompt for development and/or incomplete code/drivers

    Kernel hacking

        -->KGDB:kernel debugging with remote gdb

                -->KGDB:use kgdb over the serial console

     

    因为kgdb加入内核代码为未成熟的代码,所以要选择“显示未成熟代码选项”,kgdb再会显示。内核从2.6.25后,KGDB已被加入内核代码树中,但直到现在,还处于未成熟代码。也仅仅支持串口调试,暂没有网络调试接口。内核2.5.25以前要使用KGDB,则要打补丁。

     

    选择通过串口调试。

    代码位于内核树的:

    /kernel/kgdb.c              #KGDB stub

    /drivers/serial/kgdboc.c #KGDB串口驱动

     

    串口配置:同上

     

    目标机:

    grub.conf 配置:

     

    title Red Flag Desktop (2.6.32.8)
    root (hd0,0)
    kernel /boot/vmlinuz-2.6.32.8 ro root=/dev/sda1 3 vga=788 splash=silent resu
    me2=swap:/dev/sda2 kgdbwait kgdboc=0,115200
    initrd /boot/initrd-2.6.32.8.img

     

    kgdbwait:kgdb 让内核等待

    kgdboc:设置串口和速率

     

    开发机:

    进入linux内核目录树根。执行下面命令:

    [root@localhost linux-2.6.32.8]# gdb vmlinux  #装入未压缩的内核映像
    GNU gdb Everest Linux (6.4-2)
    Copyright 2005 Free Software Foundation, Inc.
    GDB is free software, covered by the GNU General Public License, and you are
    welcome to change it and/or distribute copies of it under certain conditions.
    Type "show copying" to see the conditions.
    There is absolutely no warranty for GDB. Type "show warranty" for details.
    This GDB was configured as "i686-pc-linux-gnu"...Using host libthread_db library "/lib/libthread_db.so.1".

    (gdb) set remotebaud 115200    #设置串口速率
    (gdb) target remote /dev/ttyS0  #连接串口1

    Remote debugging using /dev/ttyS0
    kgdb_breakpoint () at kernel/kgdb.c:1721
    1721 wmb(); /* Sync point after breakpoint */
    warning: shared library handler failed to enable breakpoint

     

    (gdb) c
    Continuing. #继续执行

     

    如果想再中断,则要在目标机上输入:

    [root@localhost linux-2.6.32.8]# echo g > /proc/sysrq-trigger
    SysRq : DEBUG

     

    或者:

    2. 中断测试系统
    为了在测试系统运行的时候让 gdb 获得控制权,需要使用 Sys-Rq。关于 Sys-Rq 的详细设置方法,见 Documentation/sysrq.txt。 你可以在系统运行时键盘上输入 Sys Rq+g,然后 gdb 就会出现:
     

  5. 用GDB调试模块:

  6. Linux 可加载模块是 ELF 格式的可执行映象;这样,它们被分成几个节.。一个典型的模块可能包含一打或更多节, 但是有 3 个典型的与一次调试会话相关:
    .text
    这个节包含有模块的可执行代码。 调试器必须知道在哪里以便能够给出回溯或者设置断点。( 这些操作都不相关, 当运行一个调试器在 /proc/kcore 上,但是它们在使用 kgdb 时可能有用,下面描述).
    .bss
    .data
    这 2 个节持有模块的变量。在编译时不初始化的任何变量在 .bss 中, 而那些要初始化的在 .data 里。使 gdb 能够处理可加载模块需要通知调试器一个给定模块的节加载在哪里.。这个信息在 sysfs 中,在 /sys/module 下。 例如, 在加载 scull 模块后,目录 /sys/module/scull/sections 包含名子为 .text 的文件;每个文件的内容是那个节的基地址。

    下面脚本可以取出这些值:

     

    # gdbline module image
    #
    # Outputs an add-symbol-file line suitable for pasting into gdb to examine
    # a loaded module.
    #
    cd /sys/module/$1/sections
    echo -n add-symbol-file $2 `/bin/cat .text`
    
    for section in .[a-z]* *; do
        if [ $section != ".text" ]; then
            echo  " //"
            echo -n "       -s" $section `/bin/cat $section`
        fi
    done
    echo
    
    目标机上执行上面脚本
    ./gdbline hello /home/test/hello.ko
    add-symbol-file /home/test/hello.ko 0xd0e1e000 /
           -s .bss 0xd0e1e7c8 /
           -s .data 0xd0e1e600 /
           -s .gnu.linkonce.this_module 0xd0e1e680 /
           -s .rodata 0xd0e1e5d0 /
           -s .rodata.str1.1 0xd0e1e448 /
           -s .rodata.str1.4 0xd0e1e508 /
           -s .strtab 0xd0e21450 /
           -s .symtab 0xd0e21000 /
           -s __param 0xd0e1e594
           

    然后开发机上,用上面输出把符号加入gdb中:

    (gdb) add-symbol-file /home/test/hello.ko 0xd0e1e000 /
           -s .bss 0xd0e1e7c8 /
           -s .data 0xd0e1e600 /
           -s .gnu.linkonce.this_module 0xd0e1e680 /
           -s .rodata 0xd0e1e5d0 /
           -s .rodata.str1.1 0xd0e1e448 /
           -s .rodata.str1.4 0xd0e1e508 /
           -s .strtab 0xd0e21450 /
           -s .symtab 0xd0e21000 /
           -s __param 0xd0e1e594
    add symbol table from file "/home/test/hello.ko" at
            .text_addr = 0xd0e1e000
            .bss_addr = 0xd0e1e7c8
            .data_addr = 0xd0e1e600
            .gnu.linkonce.this_module_addr = 0xd0e1e680
            .rodata_addr = 0xd0e1e5d0
            .rodata.str1.1_addr = 0xd0e1e448
            .rodata.str1.4_addr = 0xd0e1e508
            .strtab_addr = 0xd0e21450
            .symtab_addr = 0xd0e21000
            __param_addr = 0xd0e1e594
    (y or n) y
    Reading symbols from /home/test/hello.ko...warning: section .strtab not found in /home/test/hello.ko
    warning: section .symtab not found in /home/test/hello.ko
    done.
    (gdb) 
    	
     

     现在就可以设置断点,开始调试了。

你可能感兴趣的:(linux,Module,脚本,library,debugging,linux内核)