1. 以 KGDB模式启动内核:
[plain] view plain copy print ?
- 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
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
之后,能看到输出:
[plain] view plain copy print ?
- QEMU waiting for connection on: tcp:0.0.0.0:4321,server
QEMU waiting for connection on: tcp:0.0.0.0:4321,server
2. 在另一个终端运行 gdb:
[plain] view plain copy print ?
- 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)
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 命令,让目标机继续执行:
[plain] view plain copy print ?
- (gdb) c
- Continuing.
(gdb) c
Continuing.
4. 这时,已经可以进入到目标机系统里了。
在 QEMU里执行:
[plain] view plain copy print ?
- echo g>/proc/sysrq-trigger
echo g>/proc/sysrq-trigger
这时,控制权转到了主机上的gdb里。
5.在gdb里设置 断点在kernel/module.c 3061行 (函数do_init_module里面) 上:
[plain] view plain copy print ?
- (gdb) break kernel/module.c:3061
- Breakpoint 3 at 0xc0061fd0: file kernel/module.c, line 3061.
(gdb) break kernel/module.c:3061
Breakpoint 3 at 0xc0061fd0: file kernel/module.c, line 3061.
然后,执行 c命令。
6.在目标机里执行 insmod命令,之后,会在gdb断点出停下来:
[plain] view plain copy print ?
- 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. */
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脚本,内容如下:
[plain] view plain copy print ?
- 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
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里执行:
[plain] view plain copy print ?
- (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
(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.加入符号:
[plain] view plain copy print ?
- (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.
(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.然后,可以对模块里的函数进行断点调试:
[plain] view plain copy print ?
- (gdb) b writeback_inode
- Breakpoint 5 at 0xbf00b554: file fs/fat/inode.c, line 1574.