利用虛擬機調試內核模塊
本文描述了在虛擬機中,利用KGDB雙機聯調NBD驅動的準備過程以及使用頻率較高的調試命令。以此為例,介紹調試Linux內核以及內核模塊的一種較常用的方法。
在進行內核調試時,系統已經不會響應用戶態程序,所以需要使用兩臺計算機利用串行端口或網絡進行雙機聯調,本文介紹的是利用串行端口進行聯調。
下面詳細介紹調試的準備工作和調試過程:
1 準備工作
- 新建虛擬機,并安裝linux系統。本教程使用的是SUSE Linux Enterprise 11。
- 從kernel.org取得最新內核,截止到2011-02-11,最新的內核版本號是2.6.37。
下面列出的,是編譯nbd-server程序時必須的庫文件包。如果要調試其他驅動,則根據需要酌情下載和安裝:
- gettext,本文使用的版本是0.18.1.1。
- libxml,本文使用的版本是2.7.8。
- zlib,本文使用的版本是1.2.5。
- Glib,本文使用的版本是2.26.1。
- NBD,本文使用的版本是2.9.20。
2 開啟linux的內核調試功能
2.1 更新內核,打開KGDB
將得到的linux源代碼解壓縮到linux的/usr/src路徑下,并在同目錄下建立連接linux,連接到代碼路徑下:
localhost:/usr/src # ln -s linux-2.6.37 linux
將/boot下的config文件拷貝到/usr/src/linux下,并改名為.config。 在linux源碼路徑下面運行make menuconfig命令,開始配置內核編譯選項:
localhost:/usr/src/linux # make menuconfig
在彈出的配置換面中,確保以下編譯選項是開啟的:
CONFIG_FRAME_POINTER=y CONFIG_KGDB=y CONFIG_KGDB_SERIAL_CONSOLE=y
編譯并更新內核:
localhost:/usr/src/linux # make && make modules_install && make install
內核編譯并更新完成后,即可重新啟動計算機,并在啟動菜單中選擇從新的內核啟動。
4 配置串口
在hypervisor manager里配置兩臺虛擬機的串口。
5 安裝必要的庫
按照這個順序安裝必要的庫文件: gettextl -> libxml-> zlib -> glib 注:以上是編譯nbd-server程序時必須的庫文件包。如果要調試其他驅動,則根據需要酌情安裝。
6 開啟內核調試
6.1 開啟服務端(調試目標)
利用串口發送和接受串口消息:
localhost:/ # echo ttyS0 > /sys/module/kgdboc/parameters/kgdboc
引發內核調試斷點:
localhost:/ # echo g > /proc/sysrq-trigger
在服務端運行上面兩個命令,就使系統進入調試狀態。此時服務端已經停止用戶態響應。
6.2 開啟客戶端(調試機)
在命令行中,將當前目錄設置到linux的源碼目錄下:
localhost:/ # cd usr/src/linux
啟動gdb調試程序:
localhost:/usr/src/linux # gdb ./vmlinux
等待gdb啟動完成后,設置gdb連接服務端:
(gdb) set remotebaud 115200 (gdb) target remote /dev/ttyS0
等待gdb輸出以下消息,說明調試環境建立成功:
kgdb_breakpoint () at kernel/debug/debug_core.c:960 960 wmb();
7 開始調試
7.1 加載NBD的符號文件
恢復運行服務端:
(gdb) c
在服務端上取得NBD模塊的加載地址:
localhost:/ # cat /proc/modules
此時服務端會輸入類似如下的信息:
nbd 12427 1 - Live 0xd8831000 xt_tcpudp 2632 3 - Live 0xd8b50000 xt_pkttype 796 3 - Live 0xd8b17000
由上得出nbd的加載地址是0xd8831000。 繼續引發服務端的內核調試斷點:
localhost:/ # echo g > /proc/sysrq-trigger
在客戶端上加載nbd的符號文件:
(gdb) add-symbol-file drivers/block/nbd.ko >0xd8831000
gdb輸出如下信息,選擇y,并回車:
add symbol table from file "drivers/block/nbd.ko" at .text_addr = 0xd8831000 (y or n) y
接下來就可以使用標準的gdb命令來遠程調試了。