兩年前調試usb/ip開源項目時,就曾用虛擬機遠程調試過Windows和Linux系統內核,當時在VMware Workstation上創建兩個虛擬機進行調試,也沒有記錄下如何配置調試,只是大體的還記得。好久沒用GDB了,今天下載了QEMU源碼,編譯安裝后想調試一下,前前后后花了大概一個小時才弄懂怎么調試QEMU,在此做個記錄備忘。
個人認為用GDB調試QEMU時調試目標分為兩種,一種是用GDB調試由QEMU啟動的虛擬機,即遠程調試虛擬機系統內核,可以從虛擬機的bootloader開始調試虛擬機啟動過程,另一種是調試QEMU本身的代碼而不是虛擬機要運行的代碼。為了分析學習QEMU的源代碼,我當然要進行后一種調試,但在這里我把兩種調試的方法都說明一下:
1. 調試QEMU虛擬機內核:
鏡像文件是test1.qcow2,上述命令行中,-S表示“freeze CPU at start up”,所以運行后你看不到任何輸出。打開另一個console,運行gdb命令,如下圖:
然后在GDB內部執行“target remote localhost:1234”,1234是默認的遠程用於調試連接的端口號。然后執行命令“break *0x7c00”,這樣就將一個斷點設置在了bootloader被加載到的內存地址,接下來就任你玩了。
2. 調試QEMU源碼:
用上述命令啟動/usr/local/bin/qemu-system-x86_64,然后來到GDB命令行輸入界面,如下圖:
執行“break main”,和“break qemu_init_cpu_loop”,就在這兩個函數的開始處分別設置了一個斷點。然后執行“start”命令,看到運行到第一個斷點處停了下來,執行“c”繼續運行,又碰到了第二個斷點,執行“bt”看一下調用棧,確實調用到了qemu_init_cpu_loop函數。如果想看源代碼,執行“layout src”執行,就出現了如上圖所示的源碼窗口,接下來,隨便你玩了。
GDB調試QEMU時經常遇到SIGUSR1與SIGUSR2后停下來,解決辦法是執行命令:
(gdb) handle SIGUSR1 SIGUSR2 noprint nostop