linux内核调试环境搭建

打开一终端执行:

qemu -m 512 -kernel bzImage -append "root=/dev/sda kgdboc=ttyS0,115200 kgdbwait" -boot c -hda busybox.img -k en-us -net nic -net tap,ifname=tap0,script=no -serial tcp::4321,server

显示等待调试端链接:

QEMU waiting for connection on: tcp:0.0.0.0:4321,server。

再打开一终端

$cd linux-2.6.35.9

$gdb vmlinux

调试客户端:

(gdb) target remote localhost:4321

Remote debugging using localhost:4321

kgdb_breakpoint (new_dbg_io_ops=0xc07c27e0)

at kernel/debug/debug_core.c:967

warning: Source file is more recent than executable.

967 wmb(); /* Sync point after breakpoint */

开启运行:

(gdb) c

Continuing.

一直到虚拟机启动。

让虚拟机进入调试模式:

#echo g > /proc/sysrq-trigger

在调试端下断点:

(gdb)b sys_init_module

(这个函数名在源文件中找不到,是由宏定义SYSCALL_DEFINE3展开的)

让虚拟机开启运行:

(gdb) c

Continuing.

在虚拟机中加载模块:

#insmod globalmem.ko

此时调试端中断在函数sys_init_module中:

Breakpoint 1, sys_init_module (umod=0xb777c008, len=134933, uargs=0x81c4348 "")

at kernel/module.c:2618

2618 if (!capable(CAP_SYS_MODULE) || modules_disabled)

下断:

(gdb) b add_sect_attrs

Breakpoint 2 at 0xc017251d: file kernel/module.c, line 1160.

执行:

(gdb) c

Continuing.

Breakpoint 2, add_sect_attrs (mod=0xe0a356c0, nsect=34, secstrings=0xe0a2b621 "",

sechdrs=0xe0a2b754) at kernel/module.c:1160

1160 for (i = 0; i < nsect; i++)

用where显示调用栈:

(gdb) where

#0 add_sect_attrs (mod=0xe0a356c0, nsect=34, secstrings=0xe0a2b621 "", sechdrs=0xe0a2b754)

at kernel/module.c:1160

#1 0xc0174029 in load_module (umod=<value optimized out>, len=<value optimized out>,

uargs=<value optimized out>) at kernel/module.c:2552

#2 0xc01742e2 in sys_init_module (umod=0xb78b6008, len=134933, uargs=0x81c4348 "")

at kernel/module.c:2622

下断第1192行:

(gdb) b 1192

Breakpoint 4 at 0xc01725db: file kernel/module.c, line 1192.

按c开启运行:

(gdb) c

Continuing.

Breakpoint 4, add_sect_attrs (mod=<value optimized out>, nsect=<value optimized out>,

secstrings=<value optimized out>, sechdrs=0xe0a2b754) at kernel/module.c:1192

1192 *(gattr++) = &(sattr++)->mattr.attr;

此时打印 sattr ->name:

(gdb) p sattr ->name

$4 = 0xdf412b60 ".note.gnu.build-id"

按若干次c之后:

(gdb) p sattr ->name

$2 = 0xdf8b25e8 ".text"

(gdb) p /x sattr ->address

$4 = 0xe0a35000

(gdb) p sattr ->name

$8 = 0xdf8b2600 ".data"

(gdb) p /x sattr ->address

$10 = 0xe0a356b8

在gdb中增加调试信息:

add-symbol-file /home/gudujian/06/globalmemDriver/globalmem.ko 0xe0a35000 -s .data 0xe0a356b8

此时就可以对globalmem.ko模块中的符号,正常下断点:

(这里仅仅使用模块的两个节.data,.text如果再使用其它节那么比较麻烦,如果有脚本可以做上面的事情就很好了)。

(gdb) b globalmem_init

Breakpoint 5 at 0xe0a35448: file /home/gudujian/06/globalmemDriver/globalmem.c, line 195.

按c让程序开始运行:

(gdb) c

Continuing.

Breakpoint 5, globalmem_init () at /home/gudujian/06/globalmemDriver/globalmem.c:195

195 dev_t devno = MKDEV(globalmem_major, 0);

此时程序中断在新加载模块的module_init函数中:globalmem_init。

此时因为编译这个内核模块时带有调试信息 EXTRA_CFLAGS=-g -O0

所以可以正常调试linux模块。

不畏不惧,不言不弃,冲破风雨的阻隔,黎明就在前方!

linux内核调试环境搭建

相关文章:

你感兴趣的文章:

标签云: