最近在學着編寫一個操做系統的簡單內核,須要debug工具,咱們這裏使用gdb來進行調試,因爲虛擬機運行和本機是兩個部分,因此使用 gdb 的遠程調試技術,這裏對 gdb 常見調試以及遠程調試方式作一個總結。linux
先對在調試操做系統內核時用到的命令作一個說明(這裏省略了一部分makefile的內容):git
爲了方便調試,將debug所用到的命令作一個簡單說明github
…… # -s 這個參數指的是啓動時開啓1234端口等待gdb鏈接 # -S 是指是啓動時不自動開始運行,等待調試器的執行命令 debug: kernel.elf os-image.bin @echo 🔨🔨🔨debug🔨🔨🔨 ${QEMU} -S -s -fda os-image.bin -boot a & i386-elf-gdb -q -ex "target remote localhost:1234" -ex "symbol-file kernel.elf" ……
咱們在使用 qemu 啓動運行鏡像文件時,使用如下參數:數據庫
這個時候纔開啓了遠程端口以便讓咱們後續可以進行鏈接到該端口進行調試函數
咱們須要在編譯源代碼的時候,加上 -g
參數,以便可以將源代碼信息編譯到可執行文件中。工具
隨後咱們使用 gdb 開啓調試ui
target remote localhost:1234
鏈接到遠程端口symbol-file kernel.elf
加載具備源代碼信息編譯到可執行文件`symbol-file 能夠追蹤到編譯器提供的庫和操做系統自己的代碼
調試符號就是這些代碼內的符號,調試符號數據庫,
記錄了變量,函數 這一類符號和內存定位的關係
從而能夠用 地址相關信息追蹤到變量名,函數名spa
以後咱們就可使用gdb命令來進行調試。操作系統
命令 | 解釋 | 示例 |
---|---|---|
file <文件名> | 加載被調試的可執行程序文件。 由於通常都在被調試程序所在目錄下執行GDB,於是文本名不須要帶路徑。 | (gdb) file gdb-sample |
r | Run的簡寫,運行被調試的程序。 若是此前沒有下過斷點,則執行完整個程序;若是有斷點,則程序暫停在第一個可用斷點處。 | (gdb) r |
c | continue的簡寫,繼續執行被調試程序,直至下一個斷點或程序結束。 | (gdb) c |
b <行號> b <函數名稱> b <函數名稱> b <代碼地址> d [編號] | b: Breakpoint的簡寫,設置斷點。兩可使用「行號」「函數名稱」「執行地址」等方式指定斷點位置。 其中在函數名稱前面加「*」符號表示將斷點設置在「由編譯器生成的prolog代碼處」。若是不瞭解彙編,能夠不予理會此用法。 d: Delete breakpoint的簡寫,刪除指定編號的某個斷點,或刪除全部斷點。斷點編號從1開始遞增。 | (gdb) b 8 (gdb) b main (gdb) b main (gdb) b 0x804835c (gdb) d |
s, n | s: 執行一行源程序代碼,若是此行代碼中有函數調用,則進入該函數; n: 執行一行源程序代碼,此行代碼中的函數調用也一併執行。 s 至關於其它調試器中的「Step Into (單步跟蹤進入)」; n 至關於其它調試器中的「Step Over (單步跟蹤)」。 這兩個命令必須在有源代碼調試信息的狀況下才可使用(GCC編譯時使用「-g」參數)。 | (gdb) s (gdb) n |
si, ni | si命令相似於s命令,ni命令相似於n命令。所不一樣的是,這兩個命令(si/ni)所針對的是彙編指令,而s/n針對的是源代碼。 | (gdb) si (gdb) ni |
p <變量名稱> | Print的簡寫,顯示指定變量(臨時變量或全局變量)的值。 | (gdb) p i (gdb) p nGlobalVar |
display ... undisplay <編號> | display,設置程序中斷後欲顯示的數據及其格式。 例如,若是但願每次程序中斷後能夠看到即將被執行的下一條彙編指令,可使用命令 「display /i $pc」 其中 $pc 表明當前彙編指令,/i 表示以十六進制顯示。當須要關心彙編代碼時,此命令至關有用。 undispaly,取消先前的display設置,編號從1開始遞增。 | (gdb) display /i $pc (gdb) undisplay 1 |
i | info的簡寫,用於顯示各種信息,詳情請查閱「help i」。 | (gdb) i r |
q | quit的簡寫,退出GDB調試環境。 | (gdb) q |
help [命令名稱] | GDB幫助命令,提供對GDB名種命令的解釋說明。 若是指定了「命令名稱」參數,則顯示該命令的詳細說明;若是沒有指定參數,則分類顯示全部GDB命令,供用戶進一步瀏覽和查詢。 | (gdb) help |