Debugging Linux Kernel Modules with VirtualBox and KGDB(自己加调试方法总结)

来源:互联网 发布:计量软件stata 编辑:程序博客网 时间:2024/06/06 14:06

英文页面地址:http://allmybrain.com/2010/04/29/debugging-linux-kernel-modules-with-virtualbox-and-kgdb/

 

 

Debugging Linux Kernel Modules with VirtualBox and KGDB
Posted in April 29th, 2010
by Dennis in Programming
Tags: debugging, kernel, kgdb, linux, virtualbox

I found a few different pages with information on debugging a Linux kernel with kgdb. There wasn't a single source with all the information I needed to get set up and working though. So here is how I set things up on my Linux host machine to debug a target Linux kernel running in a VirtualBox VM.

   1.Set up the virtual machine

      When setting up the VM, add a serial port and set it to use Host Pipe. You can check the box to have VirtualBox create the pipe too. Give a path to the file on the host where you want the pipe. This will become the virtual serial console that gdb connects to on the host machine.

      Install VirtualBox with a VM containing the kernel you want to debug. Build the kernel with debug symbols, kgdb support, sysrq keys

       
      Kernel hacking->
         [*] Magic SysRq Key
         [*] Kernel debugging
         [*] Compile the kernel with debug info
         [*] KGDB: kernel debugging with remote gdb ->
            [*] KGDB: use kgdb over the serial console

   还有一个选项需要配置

    CONFIG_DEBUG_INFO:                                                    
   这是调试内核必选的开关,但是好像有的默认的config里有时没有开启。

       kernel hanking->

           [*] Compile the kernel with debug info

      Build your kernel and install the modules like you would any other kernel.

      Add kgdboc=ttyS0,115200 to the kernel paremeters (ttyS[0-3] depending on which COM port you choose in the VM setup.)现在的标准内核上好像只提供了kgdbos,没有kgdboe,但是在一般的公司中还会把kgdboe给你加上去。由于virtual box中可以选择串口。就暂且不管kgdb的方式吧。

      Copy the vmlinux (uncompressed version to the host machine).其中vmlinux中的符号表才是调试所依赖的东西
      Also copy the .ko for the module you want to debug.

      Start VM.
   2. Get the target VM ready for debugging

      After your module is inserted, you need its .text address so that you can see the source lines in gdb.

       
      cat /sys/module/XXX/sections/.text
      0xffffffffa00c0000

     这一步最好还是把text,data,bss这三个段的地址都记录下来,后面在kgdbk会用到:

    我自己的操作如下:

     cat /sys/module/tun/sections/.text,

    cat /sys/module/tun/sections/.bss,

    cat /sys/module/tun/sections/.data     

      When you're ready to start a debug session:

       
      echo g > /proc/sysrq-trigger
       

   3.Ready the Host to connect to the VM

      You need to convert the pipe that VirtualBox created to a serial port like object. socat does that job:

      Notice that your dev is pts/3.

      Now we make a .gdbinit file so you can start gdb without typing the commands every time.

       
      file vmlinux
      set remotebaud 115200
      target remote /dev/pts/3
       这个.gdbinit的文件值得利用,可以省不少事

      You'll change your pts setting to whatever is relevant.

      start gdb.

      On the target, when you send the g to sysrq-trigger, you should drop to a breakpoint in gdb.这一步好像作用不大。可以忽略掉。

      Next job is to load the module symbols.

       在gdb的命令提示符下,已经连好的目标机之后:
      > add-symbol-file
      <path to module> <.text address>
      > b some_file.c:NNN
      > c
       不过在调试时,最好把三个段的参数都放进去:

      我自己调试后,运行结果如下:
(gdb) add-symbol-file  /path/tun.ko 0xbf085000 /
          -s .data 0xbf087a58 /
          -s .bss  0xbf087be0
add symbol table from file "/buildarea1/ywang4/build/at91sam9g20-0908/build/linux-atmel_at91sam9g20-standard-build/drivers/net/tun.ko" at
    .text_addr = 0xbf085000
    .data_addr = 0xbf087a58
    .bss_addr = 0xbf087be0
(y or n) y
Reading symbols from /buildarea1/ywang4/build/at91sam9g20-0908/build/linux-atmel_at91sam9g20-standard-build/drivers/net/tun.ko...done.
到这一步,表明你的内核模块的地址和相关信息记录到kgdb中了。

在add-symbol-file 命令时,模块后面跟的三个段不加参数的地址是 text段,可以用-s参数来增加data,bss段的信息。

 

然后打断点。调试。



      Now you can set breakpoints or press c to continue. The target should continue until it comes to a breakpoint or encounters an error.

A last tidbit, when I wanted to close gdb on the host, use detach instead of quit.

Happy debugging!

 

 

在这里,我把内核调试的方法总结一下:

1. 用printk一步步跟踪,这时需要打开有关debug的相关选项。

 

2. 用kgdb调试,一般分内核的调试和动态加载模块的调试,据我看,动态加载模块只是在调试时省去了重启内核。没有太大的帮助。

 

3./sys和/proc目录的关注

/sys/modules文件夹下的各个驱动模块的信息。

/sys/cdev字符设备

/sys/block 块设备

/sys/bus 总线

/sys/power 电源管理

/sys/devices 所有的设备相关信息

 

/proc目录下的注意的文件

/proc/kallsyms表示当前系统下的所有系统调用

/proc/modules表示所有modules的状态,比lsmod命令全

 

4.使用内核中的ftrace进行调试,可以参考

http://www.uini.net/2010/06/linux-kernel-debug-using-the-ftrace-part-1.html

http://www.uini.net/2010/06/linux-kernel-debug-using-the-ftrace-part-2.html

http://www.uini.net/2010/06/linux-kernel-debug-using-the-ftrace-part-3.html

 

 

5,用户态的strace命令,例如:strace insmod tun.ko

 

6.有个systemTap的工具,我还没怎么学。网址:http://sourceware.org/systemtap/index.html

原创粉丝点击