QEMU+KGDB 调试ARM内核模块

    

        QEMU + KGDB调试内核模块             

        分类:             linux kernel                   386人阅读     评论(0)     收藏     举报    

1. 以 KGDB模式启动内核:

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

之后,能看到输出:

[plain] view plain copy print ?
  1. QEMU waiting for connection on: tcp:0.0.0.0:4321,server  

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

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

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

[plain] view plain copy print ?
  1. (gdb) c  
  2. Continuing.  

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

在 QEMU里执行:

[plain] view plain copy print ?
  1. echo g>/proc/sysrq-trigger  
这时,控制权转到了主机上的gdb里。

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

[plain] view plain copy print ?
  1. (gdb) break kernel/module.c:3061  
  2. Breakpoint 3 at 0xc0061fd0: file kernel/module.c, line 3061.  
然后,执行 c命令。


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

[plain] view plain copy print ?
  1. Breakpoint 3, do_init_module (mod=0xbf004084) at kernel/module.c:3061  
  2. 3061        if (mod->init != NULL)  
  3. (gdb) l  
  4. 3056                    mod->init_ro_size,  
  5. 3057                    mod->init_size);  
  6. 3058      
  7. 3059        do_mod_ctors(mod);  
  8. 3060        /* Start the module */  
  9. 3061        if (mod->init != NULL)  
  10. 3062            ret = do_one_initcall(mod->init);  
  11. 3063        if (ret < 0) {  
  12. 3064            /* Init routine failed: abort.  Try to protect us from  
  13. 3065                       buggy refcounters. */  


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

[plain] view plain copy print ?
  1. set $sect_num=mod->sect_attrs->nsections  
  2. set $cur=0  
  3. while $cur < $sect_num  
  4.     printf "Name:%-s Address:0x%x\n",mod->sect_attrs->attrs[$cur]->name,mod->sect_attrs->attrs[$cur]->address  
  5.     set $cur=$cur+1  
  6. end  
命名为 print-mod-sections。

然后, 在 gdb里执行:

[plain] view plain copy print ?
  1. (gdb) source print-mod-sections   
  2. Name:.text Address:0xbf005000  
  3. Name:.init.text Address:0xbf012000  
  4. Name:.exit.text Address:0xbf00d624  
  5. Name:.text.unlikely Address:0xbf00d644  
  6. Name:.note.gnu.build-id Address:0xbf00d728  
  7. Name:__ksymtab_gpl Address:0xbf00d74c  
  8. Name:.rodata Address:0xbf00d800  
  9. Name:.rodata.str Address:0xbf00dd5c  
  10. Name:__bug_table Address:0xbf00ddef  
  11. Name:.alt.smp.init Address:0xbf00de68  
  12. Name:.ARM.exidx.init.text Address:0xbf00df00  
  13. Name:.rodata.str1.4 Address:0xbf00df10  
  14. Name:__ksymtab_strings Address:0xbf00ec88  
  15. Name:.ARM.extab.exit.text Address:0xbf00ed9c  
  16. Name:.ARM.exidx.exit.text Address:0xbf00eda8  
  17. Name:.ARM.extab.text.unlikely Address:0xbf00edb0  
  18. Name:.ARM.exidx.text.unlikely Address:0xbf00edc8  
  19. Name:.ARM.extab Address:0xbf00edd8  
  20. Name:.data Address:0xbf00f130  
  21. Name:.gnu.linkonce.this_module Address:0xbf00f184  
  22. Name:.ARM.exidx Address:0xbf00edf0  
  23. Name:.bss Address:0xbf00f2d4  
  24. Name:.symtab Address:0xbf0120b4  
  25. ---Type <return> to continue, or q <return> to quit---  
  26. Name:.strtab Address:0xbf014734  

8.加入符号:

[plain] view plain copy print ?
  1. (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  
  2. add symbol table from file "/home/charles/code/linux-3.10.28/fs/fat/fat.ko" at  
  3.     .text_addr = 0xbf005000  
  4.     .data_addr = 0xbf00f130  
  5.     .bss_addr = 0xbf00f2d4  
  6.     .init.text_addr = 0xbf012000  
  7. (y or n) y  
  8. Reading symbols from /home/charles/code/linux-3.10.28/fs/fat/fat.ko...done.  
9.然后,可以对模块里的函数进行断点调试:

[plain] view plain copy print ?
  1. (gdb) b writeback_inode  
  2. Breakpoint 5 at 0xbf00b554: file fs/fat/inode.c, line 1574.  

你可能感兴趣的:(linux,kernel)