用 kGDB 調試 Linux 核心

來源:互聯網
上載者:User

標籤:linux   kgdb   調試   

by Pingbo Wen of TinyLab.org
2013/08/11

簡介

這個文檔記錄了用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=5CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=1CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=1CONFIG_S3C2410_WATCHDOG_ATBOOT=0CONFIG_FRAME_POINTER -- 使KDB能夠列印更多的棧資訊CONFIG_KALLSYMS -- 加入符號資訊CONFIG_KDB_KEYBOARD -- 如果是通過目標版的鍵盤與KDB通訊,需要把這個開啟,且鍵盤不能是USB介面CONFIG_KGDB_TESTS
啟動參數

開啟相應的選項後,需要配置kernel啟動參數,使KGDB和核心能夠找到正確的通訊介面。如果是使用串口,則需要配置如下選項:

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 ++++++++++++++++++++++1 files changed, 22 insertions(+), 0 deletions(-)diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.cindex 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)+{+    while (!(rd_regl(port, S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXE))+       ;++     wr_regl(port, S3C2410_UTXH, c);+}++static int s3c24xx_serial_poll_get_char(struct uart_port *port)+{+    while (!(rd_regl(port, S3C2410_UTRSTAT) & S3C2410_UTRSTAT_RXDR))+       ;++    return rd_regl(port, S3C2410_URXH);+}+#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

加入這個patch,重新編譯核心,之後就能正常進入kgdb

gdb遠端偵錯

如果在核心啟動參數中加入了kgdbwait,則核心會在完成基本的初始化之後,停留在kgdb的調試陷阱中,等待主機的gdb的遠端連線。

由於大部分的板子只有一個調試串口,所以你需要把之前與串口通訊的minicom退出來,然後在核心源碼的目錄下,執行以下命令:

$ arm-linux-gnueabi-gcc vmlinux(gdb) target remote /dev/ttyUSB0(gdb) set detach-on-fork on(gdb) b panic()(gdb) c

當然,你也可以agent-proxy來複用一個串口,通過虛擬出兩個TCP連接埠。這時候,gdb就需要用target
remote命令串連kgdb,例如:

(gdb) target remote localhost:5551

agent-proxy可以通過這裡擷取:git://git.kernel.org/pub/scm/utils/kernel/kgdb/agent-proxy.git,具體用法,請看該repo下的README。

在用gdb來調試核心的時候,由於核心在初始化的時候,會建立很多子線程。而預設gdb會接管所有的線程,如果你從一個線程切換到另外一個線程,gdb會馬上把原先的線程暫停。但是這樣很容易導致kernel死掉,所以需要設定一下gdb。
一般用gdb進行多線程調試,需要注意兩個參數:follow-fork-mode和detach-on-fork。

  • detach-on-fork參數,指示GDB在fork之後是否斷開(detach)某個進程的調試,或者都交由GDB控制:

    set detach-on-fork [on|off]

    • on: 斷開調試follow-fork-mode指定的進程。
    • off: gdb將控制父進程和子進程。
  • follow-fork-mode指定的進程將被調試,另一個進程置於暫停(suspended)狀態。follow-fork-mode的用法為:

    set follow-fork-mode [parent|child]

    • parent: fork之後繼續調試父進程,子進程不受影響。
    • child: fork之後調試子進程,父進程不受影響。
REFERENCE
  • gdb user
    mannual: http://sourceware.org/gdb/current/onlinedocs/gdb/
  • gdb
    internal: http://www.sourceware.org/gdb/onlinedocs/gdbint.html
  • kgdb/kdb official
    website: https://kgdb.wiki.kernel.org/
  • kernel debug
    usage: http://www.kernel.org/doc/htmldocs/kgdb.html
  • kdb in elinux.org: http://elinux.org/KDB
  • multi-threads debug in
    gdb: http://www.ibm.com/developerworks/cn/linux/l-cn-gdbmp/
  • KGDB.info: http://www.kgdb.info/

用 kGDB 調試 Linux 核心

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.