歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux綜合 >> Linux內核

用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

Copyright © Linux教程網 All Rights Reserved