QEMU + KGDB调试内核模块

1. 以 KGDB模式启动内核:

 sudo ./qemu-1.7.0/arm-softmmu/qemu-system-arm  -M vexpress-a9 -kernel ./linux-3.10.28/arch/arm/boot/zImage
 -sd rootfs.img --append "root=/dev/mmcblk0 rw rootfs=ext3 rootdelay=3  physmap.enabled=0 console=ttyAMA0 
console=tty0 kgdboc=tty0,115200 kgdbwait"  -net nic,vlan=0 -net tap,vlan=0  -serial tcp::4321,server

之后,能看到输出:

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

2. 在另一个终端运行 gdb:

arm-linux-gdb vmlinux
GNU gdb (GDB) 7.7
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=i686-pc-linux-gnu --target=arm-linux".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from vmlinux...done.
(gdb) target remote localhost:4321
Remote debugging using localhost:4321
Bogus trace status reply from target: OK
(gdb) target remote localhost:4321
Remote debugging using localhost:4321
0xc006c21c in arch_kgdb_breakpoint ()
    at /home/charles/code/linux-3.10.28/arch/arm/include/asm/outercache.h:103
103			outer_cache.sync();
(gdb) 

3. 执行 c 命令,让目标机继续执行:

(gdb) c
Continuing.

4. 这时,已经可以进入到目标机系统里了。

在 QEMU里执行:

echo g>/proc/sysrq-trigger
这时,控制权转到了主机上的gdb里。

5.在gdb里设置 断点在kernel/module.c 3061行 (函数do_init_module里面) 上:

(gdb) break kernel/module.c:3061
Breakpoint 3 at 0xc0061fd0: file kernel/module.c, line 3061.
然后,执行 c命令。


6.在目标机里执行 insmod命令,之后,会在gdb断点出停下来:

Breakpoint 3, do_init_module (mod=0xbf004084) at kernel/module.c:3061
3061        if (mod->init != NULL)
(gdb) l
3056                    mod->init_ro_size,
3057                    mod->init_size);
3058    
3059        do_mod_ctors(mod);
3060        /* Start the module */
3061        if (mod->init != NULL)
3062            ret = do_one_initcall(mod->init);
3063        if (ret < 0) {
3064            /* Init routine failed: abort.  Try to protect us from
3065                       buggy refcounters. */


7 写一个gdb脚本,内容如下:

set $sect_num=mod->sect_attrs->nsections
set $cur=0
while $cur < $sect_num
    printf "Name:%-s Address:0x%x\n",mod->sect_attrs->attrs[$cur]->name,mod->sect_attrs->attrs[$cur]->address
    set $cur=$cur+1
end
命名为 print-mod-sections。

然后, 在 gdb里执行:

(gdb) source print-mod-sections 
Name:.text Address:0xbf005000
Name:.init.text Address:0xbf012000
Name:.exit.text Address:0xbf00d624
Name:.text.unlikely Address:0xbf00d644
Name:.note.gnu.build-id Address:0xbf00d728
Name:__ksymtab_gpl Address:0xbf00d74c
Name:.rodata Address:0xbf00d800
Name:.rodata.str Address:0xbf00dd5c
Name:__bug_table Address:0xbf00ddef
Name:.alt.smp.init Address:0xbf00de68
Name:.ARM.exidx.init.text Address:0xbf00df00
Name:.rodata.str1.4 Address:0xbf00df10
Name:__ksymtab_strings Address:0xbf00ec88
Name:.ARM.extab.exit.text Address:0xbf00ed9c
Name:.ARM.exidx.exit.text Address:0xbf00eda8
Name:.ARM.extab.text.unlikely Address:0xbf00edb0
Name:.ARM.exidx.text.unlikely Address:0xbf00edc8
Name:.ARM.extab Address:0xbf00edd8
Name:.data Address:0xbf00f130
Name:.gnu.linkonce.this_module Address:0xbf00f184
Name:.ARM.exidx Address:0xbf00edf0
Name:.bss Address:0xbf00f2d4
Name:.symtab Address:0xbf0120b4
---Type <return> to continue, or q <return> to quit---
Name:.strtab Address:0xbf014734



8.加入符号:

(gdb) add-symbol-file /home/charles/code/linux-3.10.28/fs/fat/fat.ko  0xbf005000 -s .data 0xbf00f130 -s .bss 0xbf00f2d4 -s .init.text 0xbf012000
add symbol table from file "/home/charles/code/linux-3.10.28/fs/fat/fat.ko" at
	.text_addr = 0xbf005000
	.data_addr = 0xbf00f130
	.bss_addr = 0xbf00f2d4
	.init.text_addr = 0xbf012000
(y or n) y
Reading symbols from /home/charles/code/linux-3.10.28/fs/fat/fat.ko...done.
9.然后,可以对模块里的函数进行断点调试:

(gdb) b writeback_inode
Breakpoint 5 at 0xbf00b554: file fs/fat/inode.c, line 1574.

参考:

1. http://www.kgdb.info/kgdb/use_kgdb/kgdb%E8%B0%83%E8%AF%95%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9/

2. https://www.kernel.org/doc/htmldocs/kgdb/EnableKGDB.html

你可能感兴趣的:(QEMU + KGDB调试内核模块)