Linux Kernel Development / Debugging (3) - Kernel Module Debugging with GDB/KGDB
此篇文章延續前文 ─ “Linux Kernel Development / Debugging (1) - 第一次玩 qemu/kgdb 就上手”,簡單介紹如何使用 gdb / kgdb 對核心模組 (kernel module) 進行即時的 debugging。
在先前的文章中,介紹了如何使用 qemu、kgdb、gdb 對核心進行動態的 debugging,並在編譯核心時在 vmlinux 中包含 debugging information,使 debug 時能夠直接瀏覽原始碼以及對變數進行存取。然而,kernel module 是在核心之外的,因次就算編譯時加上 -g GCCFLAG 也無法直接在 gdb 中存取其 debugging information。
要解決這個問題,需要使用 gdb 中的 add-symbol-file 命令來讀入包含 debugging information 的 kernel module。gdb 與核心、模組是執行在完全不同的電腦上,因次 gdb 是無法直接得知 insmod 之後 kernel module 被載入到記憶體中的位置,也讓 module debugging 變得比較 tricky 一點。以下是我的作法:
- 在 kernel module 中的 init_module 中插入 break point stub ‘asm(” int $3”);’,使得 module 在一被載入後馬上發出中斷,以便動態設定中斷點。在其他想要 debug 的 function 中也加入中斷點,並至少設定一個可以從 user space 觸發的中斷。
- 編譯模組,並將 -g (-O0) 加入EXTRA_CFLAGS,讓編譯好的模組包含 debugging information。
- 在 qemu 中使用 insmod 指令載入編譯好的模組。載入後的中斷先在 gdb 中用 continue 指令跳過。
- 在 /sys/modules/<module_name>/sections/.text 中找到 kernel module 在記憶體中的位置。然後觸發任何於 kernel 中的中斷點。
- 在 gdb 中使用 add-symbol-file <module> <location> 載入 kernel module 的 debugging information,便可以開始做 kernel module debugging。

Reference