感謝Scott 大大糾正,選錯平台,這篇使用了ARMv4指令集的測試平台。請大家忽略,正確的版本將會之後更新!
前言
還是感謝Scott大大和其他網友的幫忙。這次最重要的心得就是不要在睡眠不足的時候做實驗,浪費的時間拿去睡覺反而比較實在。
目錄
測試環境
Host
- Host OS
1 2 3 4 5 6 |
|
- Qemu
1 2 |
|
- gdb
1 2 3 4 5 |
|
- buildroot 版本
- commit hash:
14b24726a81b719b35fee70c8ba8be2d682a7313
- commit hash:
Target
- Linux kernerl 版本
- 4.4.2
- 模擬平台
- Versatile
Linux kernel環境設定
我目前只打開加入debug資訊的選項。接下來重編,編譯的方式請參考這邊
- Kernel hacking -> Compile-time checks and compiler options ->
- Compile the kernel with debug info
測試
依照下面兩個步驟執行
- 執行qemu,並且加入支援gdb以及開始馬上freeze CPU的參數
- 執行gdb,載入symbol並聯到qemu除錯
Qemu
基本上就是原本的指令加入兩個選項
-S
- qemu一開始立即Freeze CPU
-s
-gdb tcp::1234
的縮寫,也就是說gdb可以透過port 1234和連到Qemu除錯
假設你在buildroot最上層,就可以使用下面指令執行qemu 並使用gdb 除錯
1 2 3 4 5 |
|
gdb
這邊有點瑣碎,先講一下步驟
- 載入Linux kernel symbol
- 假設你在kernel最上層目錄有三種方式載入
- 直接
arm-none-eabi-gdb ./vmlinux
arm-none-eabi-gdb -ex "file ./vmlinux"
- 進入gdb後打
file ./vmlinux
指令
- 直接
- 假設你在kernel最上層目錄有三種方式載入
- 連上qemu
- 一樣兩種方式
arm-none-eabi-gdb -ex "target remote :1234"
- 進入gdb後打
target remote :1234
指令
- 一樣兩種方式
- 設定breakpoint等你要觀察的資訊
- 如
b printk
- 如
- 告訴qemu開始執行
continue
1和2可以一起使用如下
1
|
|
現在看一下操作範例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
另外如果有興趣使用Linux kernel提供的指令,可以使用下面的方式在啟動gdb時載入
,只要把下面的描述加到你的~/.gdbinit
即可
1
|
|
那麼你就可以使用Linux kernel提供的gdb script,詳細的設定和指令說明在這邊。
參考資料
- Linux Magazine: Qemu and the Kernel
- Linux kernel document: Debugging kernel and modules via gdb
- stackoverflow: How to debug the Linux kernel with GDB and QEMU?
補充
當初犯了蠢事載入不正確的kernel image導致一堆不必要的除錯。不過多學到一個gdb Python script除錯指令,當Python script發生exception時可以用下面的指令印出Python錯誤call stack
- gdb內:
set python print-stack full
- 啟動gdb時加入參數:
-ex "set python print-stack full"