感谢支持
我们一直在努力

用DDD+GDB+QEMU 进行Linux内核源码级调试

在看此文章之前,请先参考《利用busybox制作一个小巧的Linux系统》http://www.linuxidc.com/Linux/2011-08/40881.htm与《使用busybox做一个小巧的Linux操作系统》 见 http://www.linuxidc.com/Linux/2008-04/12510.htm 制作出一个initrd内存盘。


1. 首先编译内核,编译内核时注意要选中


    kernel hacking –> kernel debugging –> compile the kernel with debug info


    kernel hacking –> compile the kernel with frame pointers


  两个选项。(注意:除此之外kernel hacking 选项下其他的选项都不要选,否则会出现断点无法拦截的情况。)


2. 假设你的内核目录位于/home/xxx/linux-2.6.28中,且编译内核时你指定的大O参数指定的目录是O=/home/xxx/linux-2.6.28-obj。


用新编译的带调试信息的内核,启动一个虚拟机。


$ qemu –kernel /home/xxx/linux-2.6.28-obj/arch/x86/boot/bzImage –append “root=/dev/ram0 rw”


-initrd /home/initrd.gz –s –S [qemu文档:http://qemu.weilnetz.de/qemu-doc.html]



-s-->Shorthand for -gdb tcp::1234, i.e. open agdbserver on TCP port 1234


-S-->Donot start CPU at startup (you must type ‘c’ in the monitor)


这样启动虚拟机后,它会在1234端口产生一个gdb stub以供调试时使用。


然后我们打开令一个xterm终端运行gdb命令开始调试:


$ gdb /home/xxx/linux-2.6.28-obj/vmlinux




#######若未使用-s参数,则可按下面启用调试##########


然后会出现qemu的工作终端,你在上面点击鼠标可以陷入,ctrl+ alt + 2可以释放鼠标


(qemu)gdbservertcp::1234 [若使用了-s参数则无需此步]


##################################


然后在gdb的提示符下输入: target remote localhost:1234 连接gdb stub


然后开始设置断点,比如: break start_kernel


然后输入c命令,然后qemu继续运行后,就会在start_kernel 入口处停了下来。


这时候你就可以输入各种gdb命令来对linux kernel进行hack了。。


当然,这里采用gdb的一个前端工具ddd会更好。但还是需要学习一些常用的gdb命令(这样才能更熟练的进行调试)


 


常用的gdb调试命令:


1. file <文件名> :  加载被调试的可执行程序文件.


2. run(简写r也可以): 运行被调试程序,直到遇到断点.


3. c : 继续执行被调试程序,直到下一断点.


4. b : 设置断点.


5. d <编号> : 删除断点.


6. info breakpoints : 显示已设置的断点列表.


7. s : 源码级的单步进入.


8. n : 源码级的单步步过.


9. si/ni : 指令级的单步进入和步过.(需要先运行display /i $pc)


10. info all-register: 显示所有寄存器的值.


11. p /x $eax : 以16进制显示某一特定寄存器的值.


12. q: 退出gdb调试环境.


13. disassemble <0xXXXXXXXX> : 反汇编指定地址处的指令.(加/r选项,显示对应汇编代码的机器码)


14. set disassembly-flavor <intel | att> : 设定汇编显示的格式(Intel格式或者AT&T格式)


15. 修改指定地址的内存数据:set {unsigned char} <0xXXXXXXXX>= <new data>


16. 显示源代码文件: list


17. info stack: 查看栈追踪(栈回溯). 或者使用 backtrace 也可以


18. x /nfu <addr> : 查看指定地址处的内存内容.


     n: 表示个数.   f(format): x,16进制.  d,10进制.   u(每一项的长度): b,单字节. w,4字节. h,双字节.


     例如: x /1xw 0x804a010

赞(0) 打赏
转载请注明出处:服务器评测 » 用DDD+GDB+QEMU 进行Linux内核源码级调试
分享到: 更多 (0)

听说打赏我的人,都进福布斯排行榜啦!

支付宝扫一扫打赏

微信扫一扫打赏