|
*在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处被暂停。
| Linux服务器傻瓜式安装完全接触 | 08-31 |
| Linux中新闻组服务器和客户端的使 | 08-14 |
| Linux下查找漏洞的几种必备工具 | 08-13 |
| Linux操作系统上摄像头的使用小技 | 08-11 |
| 网络工程师 Linux系统日志的分析 | 08-08 |
| Ubuntu 7.04操作系统下安装Man在 | 07-27 |
| 从USB移动硬盘上引导Portable Li | 07-27 |
| Ghost程序参数四则 系统备份与恢 | 07-27 |
| 系统安全:分级防御对Linux服务器 | 07-24 |
| Linux操作系统中厉害的“七种武器 | 07-21 |
| 体系架构是不是桌面Linux系统的弱 | 07-19 |
| Linux系统的各种后门和日志工具详 | 07-19 |