這個文件記錄了用kgdb除錯linux核心的全過程,都是在前人工作基礎上的一些總結。以下操作都是基於特定板子來進行,但是大部分都能應用於其他平台。
要使用kgdb來除錯核心,首先需要修改config配置檔案,開啟相應的配置,配置核心啟動引數,甚至修改串列埠驅動新增poll支援,然後才能通過串列埠遠端除錯核心。
在核心配置檔案:.config中,需要開啟如下選項
config_kgdb
加入kgdb支援
config_kgdb_serial_console
使kgdb通過串列埠與主機通訊(開啟這個選項,缺省會開啟config_console_poll和config_magic_sysrq)
config_kgdb_kdb
加入kdb支援
config_debug_kernel
包含驅動除錯資訊
config_debug_info
使核心包含基本除錯資訊
config_debug_rodata=n
關閉這個,能在唯讀區域設定斷點
config_panic_timeout=5開啟相應的選項後,需要配置kernel啟動引數,使kgdb和核心能夠找到正確的通訊介面。如果是使用串列埠,則需要配置如下選項:config_bootparam_softlockup_panic_value=1
config_bootparam_hung_task_panic_value=1
config_s3c2410_watchdog_atboot=0
config_frame_pointer -- 使kdb能夠列印更多的棧資訊
config_kallsyms -- 加入符號資訊
config_kdb_keyboard -- 如果是通過目標版的鍵盤與kdb通訊,需要把這個開啟,且鍵盤不能是usb介面
config_kgdb_tests
console=ttysac3,115200 kgdboc=ttysac3,115200如果需要除錯核心的啟動過程,則需要在kgdboc後面加入kgdbwait。
在其他板子上,若使用乙太網口來和kgdb進行通訊,則要把kgdboc換成kgdboe(kgdb
over ethernet))。
kgdb: unregistered i/o driver, debugger disabled.則需要根據這一部分,修改串列埠驅動程式,若能正常進入kgdb,則忽略該節,直接進入下一節使用kgdb。
在drivers/tty/serial/kgdboc.c中的configure_kgdboc函式,會通過tty_find_polling_driver(cptr,
&tty_line)來找尋核心啟動引數中指定的串列埠驅動。然後通過kgdboc_get_char()和kgdboc_put_char()來和主機串列埠正常通訊。
可以看到在config配置檔案的config_console_poll就是使能串列埠與kgdboc的介面。如果 tty_find_polling_driver沒有找到對應的串列埠通訊介面,則會呼叫kernel/debug/debug_core.c中的 kgdb_unregister_io_module進行錯誤處理。
有的板子的串列埠驅動並沒有加入對kgdboc通訊的支援,例如samsung的串列埠驅動需要在drivers/tty/serial/samsung.c中手動新增。
新增與kgdboc通訊的介面,只需新增乙個傳送函式和接收函式,然後在驅動操作結構體中加入對應的函式就可以了。具體的patch如下:
drivers/tty/serial/samsung.c | 22 ++++++++++++++++++++++加入這個patch,重新編譯核心,之後就能正常進入kgdb1 files changed, 22 insertions(+), 0 deletions(-)
diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c
index ff6a4f8..5ceb7d7 100755
--- a/drivers/tty/serial/samsung.c
+++ b/drivers/tty/serial/samsung.c
@@ -893,7 +893,29 @@ static struct console s3c24xx_serial_console;
#define s3c24xx_serial_console null
#endif
+#ifdef config_console_poll
+static void s3c24xx_serial_poll_put_char(struct uart_port *port, unsigned char c)++
+static int s3c24xx_serial_poll_get_char(struct uart_port *port)
++#endif
+static struct uart_ops s3c24xx_serial_ops = {
+#ifdef config_console_poll
+ .poll_get_char = s3c24xx_serial_poll_get_char,
+ .poll_put_char = s3c24xx_serial_poll_put_char,
+#endif
.pm = s3c24xx_serial_pm,
.tx_empty = s3c24xx_serial_tx_empty,
.get_mctrl = s3c24xx_serial_get_mctrl,
--1.7.5.4
如果在核心啟動引數中加入了kgdbwait,則核心會在完成基本的初始化之後,停留在kgdb的除錯陷阱中,等待主機的gdb的遠端連線。
由於大部分的板子只有乙個除錯串列埠,所以你需要把之前與串列埠通訊的minicom退出來,然後在核心原始碼的目錄下,執行以下命令:
$ arm-linux-gnueabi-gcc vmlinux當然,你也可以agent-proxy來復用乙個串列埠,通過虛擬出兩個tcp埠。這時候,gdb就需要用target(gdb) target remote /dev/ttyusb0
(gdb) set detach-on-fork on
(gdb) b panic()
(gdb) c
remote命令連線kgdb,例如:
(gdb) target remote localhost:5551agent-proxy可以通過這裡獲取:git:具體用法,請看該repo下的readme。
在用gdb來除錯核心的時候,由於核心在初始化的時候,會建立很多子執行緒。而預設gdb會接管所有的執行緒,如果你從乙個執行緒切換到另外乙個執行緒,gdb會馬上把原先的執行緒暫停。但是這樣很容易導致kernel死掉,所以需要設定一下gdb。
一般用gdb進行多執行緒除錯,需要注意兩個引數:follow-fork-mode和detach-on-fork。
follow-fork-mode指定的程序將被除錯,另乙個程序置於暫停(suspended)狀態。follow-fork-mode的用法為:
set follow-fork-mode [parent|child]
ubuntu用qemu除錯linux核心
出於對用虛擬機器 除錯 核心 看是否能對學習核心有比較大的幫助。進行了下驗證 中間 的命令僅作為參考,是使用過程中的一些記錄,檔案命名 路徑名 使用時 作出對應調整 需。wget 解壓 tar xvf linux 3.10.104.tar.xz cd linux 3.10.104 進行配置 make...
kgdb除錯注意事項
0 首先提下注意事項的背景 kgdb和printk共用乙個串列埠 1設定波特率 最高支援460800波特率 arm eabi gdb vmlinux gdb set remotebaud 460800 設定使用哪個埠,作為通訊埠 gdb target remote dev ttyusb0 2 使用的...
linux 核心除錯
debug.hacks 一書中,介紹了如果除錯核心問題,在第五章的 實踐核心除錯 總體來說,有一下的方法來除錯核心 1.用kgdb單步除錯。具體請參見 2.加列印printk來定位。3.根據核心出錯的kernel panic oops資訊,反彙編,定位問題 4.編寫復現程式,或者創造復現條件。5.g...