黑客风云——风云网络
设为首页 加入收藏 我要投稿 网站地图
您现在的位置: 黑客风云 >> 黑客文章 >> 操作系统 >> LINIX UNIX >> 文章正文
[推荐]使用kgdb调试linux内核及内核模块
      ★★★
使用kgdb调试linux内核及内核模块
文章整理发布:黑客风云 文章来源:www.05112.com 更新时间:2006-10-4

  *在target机器上

引导2.4.23-kgdb内核,内核将在短暂的运行后暂停并进入调试状态,打印如下信息:
Waiting for connection from remote gdb...

  *在developer机器上

#cd /home/liangjian/linux-2.4.23
# gdb vmlinux
GNU gdb Red Hat Linux (5.3post-0.20021129.18rh)
Copyright 2003 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 "i386-redhat-linux-gnu"...

  执行rmt宏

(gdb) rmt
breakpoint () at kgdbstub.c:1005
1005                    atomic_set(&kgdb_setting_breakpoint, 0);

  查看当前堆栈

(gdb) bt
#0  breakpoint () at kgdbstub.c:1005
#1  0xc0387fe0 in init_task_union ()
#2  0xc01bc984 in gdb_hook () at gdbserial.c:250
#3  0xc0388898 in start_kernel () at init/main.c:443

  在do_basic_setup函数处设置断点,并让内核恢复运行

(gdb) b do_basic_setup
Breakpoint 1 at 0xc0388913: file current.h, line 9.
(gdb) continue
Continuing.
[New Thread 1]
[Switching to Thread 1]

Breakpoint 1, do_basic_setup () at current.h:9
9               __asm__("andl %%esp,%0; ":"=r" (current) : "0" (~8191UL));

  内核在do_basic_setup断点处停止运行后查看当前堆栈

(gdb) bt
#0  do_basic_setup () at current.h:9
(gdb)

  3.3.3 内核模块调试调试

  要想调试内核模块,需要相应的gdb支持,kgdb的主页上提供了一个工具gdbmod,它修正了gdb 6.0在解析模块地址时的错误,可以用来正确的调试内核模块

  *在developer机器上

  写了个测试用的内核模块orig,如下:

void xcspy_func()
{
    printk("<1>xcspy_func\n");
    printk("<1>aaaaaaaaaaa\n");
}

int xcspy_init()
{
    printk("<1>xcspy_init_module\n");
       
    return 0;
}

void xcspy_exit()
{
    printk("<1>xcspy_cleanup_module\n");
}

module_init(xcspy_init);
module_exit(xcspy_exit);

  编译该模块:

#cd /home/liangjian/lkm
#gcc -D__KERNEL__ -DMODULE -I/home/liangjian/linux-2.4.23/include -O -Wall -g -c -o orig.o orig.c
#scp orig.o root@192.168.16.30:/root

  开始调试:

# gdbmod vmlinux
GNU gdb 6.0
Copyright 2003 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"...

  设置符号文件的搜索路径

(gdb) set solib-search-path /home/liangjian/lkm

  执行rmt宏

(gdb) rmt
breakpoint () at kgdbstub.c:1005
1005                    atomic_set(&kgdb_setting_breakpoint, 0);

  设置断点使得可以调试内核模块的init函数,查内核源码可知,内核是通过module.c文件的第566行(sys_init_module函数中)mod->init来调用模块的init函数的

(gdb) b module.c:566
Breakpoint 1 at 0xc011cd83: file module.c, line 566.
(gdb) c
Continuing.
[New Thread 1352]
[Switching to Thread 1352]

  这时在target机器上执行insmod orig.o,developer则相应的在断点处被暂停,如下
                                                                                                                         
Breakpoint 1, sys_init_module (name_user=0xc03401bc "\001",
mod_user=0x80904d8) at module.c:566
566             if (mod->init && (error = mod->init()) != 0) {

  使用step命令进入模块的init函数

(gdb) step
xcspy_init () at orig.c:12
12              printk("<1>xcspy_init_module\n");
(gdb) n
15      }
(gdb)

  说明:

  调试内核模块的非init函数相对比较简单,只要先在target上执行insmod orig.o,这时由于模块的符号被加载,可以直接在developer的gdb中对想调试的模块函数设置断点,如bt xcspy_func,后面当xcspy_func被调用时就进入了调试状态。

  如果想调试内核模块的init函数,由于在执行insmod之前模块的符号还没有被加载,不能直接对模块的init函数设置断点,所以相对来说要困难一些。可以采用两种变通的方法:1,采用上面介绍的在内核调用模块的init函数被调用之前的某处插入断点,如bt sys_init_module()或bt module.c:566;2,在developer上让内核处于运行状态,在target上先执行一遍insmod orig.o,这时orig.o的符号已经被加载到内存中,可以直接在developer的gdb中对模块的init函数设置断点,如bt xcspy_init,然后在target上rmmod orig.o,当下次在target上重新加载orig.o时就进入了调试状态,developer在xcspy_init处被暂停。

上一页  [1] [2] [3] 

文章录入:sygbox    责任编辑:sygbox 
【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
VIP 专 区
Copyright @2006 黑客风云 ●业务联系:QQ 联系怪人 联系奇人 Email:给怪人发邮件 给奇人发邮件
ICP备案:冀06009886