电竞比分网-中国电竞赛事及体育赛事平台

分享

利用GDB和Bochs調(diào)試內(nèi)核源代碼

 lchjczw 2012-12-12
本節(jié)說(shuō)明如何在現(xiàn)有Linux系統(tǒng)(例如RedHat 9)上使用Bochs模擬運(yùn)行環(huán)境和gdb工具來(lái)調(diào)試Linux0.11內(nèi)核源代碼。在使用這個(gè)方法之前,你的Linux系統(tǒng)上應(yīng)該已經(jīng)安裝有Xwindow系統(tǒng)。由于Bochs網(wǎng)站提供的RPM安裝包中的Bochs執(zhí)行程序沒(méi)有編譯進(jìn)與gdb調(diào)試器進(jìn)行通信的gdbstub模塊,因此我們需要下載Bochs源代碼來(lái)自行編譯。
    gdbstub可以使得Bochs程序在本地1234網(wǎng)絡(luò)端口偵聽(tīng)接收gdb的命令,并且向gdb發(fā)送命令執(zhí)行結(jié)果。從而我們可以利用gdb對(duì)Linux 0.11內(nèi)核進(jìn)行C語(yǔ)言級(jí)的調(diào)試。當(dāng)然,Linux 0.11內(nèi)核也需要進(jìn)行使用-g選項(xiàng)重新編譯。
14.13.1 編譯帶gdbstub的Bochs系統(tǒng)
    Bochs用戶(hù)手冊(cè)中介紹了自行編譯Bochs系統(tǒng)的方法。這里我們給出編譯帶gdbstub的Bochs系統(tǒng)的方法和步驟。首先從下面網(wǎng)站下載最新Bochs系統(tǒng)源代碼(例如:bochs-2.2.tar.gz):
    [url]http:///projects/bochs/[/url]
    使用tar對(duì)軟件包解壓后會(huì)在當(dāng)前目錄中生成一個(gè)bochs-2.2子目錄。進(jìn)入該子目錄后帶選項(xiàng)“--enable-gdb-stub”運(yùn)行配置程序configure,然后運(yùn)行make和make install即可,見(jiàn)如下所示:
[root@plinux bochs-2.2]# ./configure --enable-gdb-stub
checking build system type... i686-pc-linux-gnu
checking host system type... i686-pc-linux-gnu
checking target system type... i686-pc-linux-gnu
...
[root@plinux bochs-2.2]# make
[root@plinux bochs-2.2]# make install
    若在運(yùn)行./configure時(shí)我們碰到一些問(wèn)題而不能生成編譯使用的Makefile文件,那么這通常是由于沒(méi)有安裝X window開(kāi)發(fā)環(huán)境軟件或相關(guān)庫(kù)文件造成的。此時(shí)我們就必須先安裝這些必要的軟件。

14.13.2 編譯帶調(diào)試信息的Linux 0.11內(nèi)核
   通過(guò)把Bochs的模擬運(yùn)行環(huán)境與gdb符號(hào)調(diào)試工具聯(lián)系起來(lái),我們既可以使用Linux0.11系統(tǒng)下編譯的帶調(diào)試信息的內(nèi)核模塊來(lái)調(diào)試,也可以使用在RedHat9環(huán)境下編譯的0.11內(nèi)核模塊來(lái)調(diào)試。這兩種環(huán)境下都需要對(duì)0.11內(nèi)核源代碼目錄中所有Makefile文件進(jìn)行修改,即在其中編譯標(biāo)志行上添加-g標(biāo)志,并去掉鏈接標(biāo)志行上的-s選項(xiàng):
LDFLAGS = -M -x                                         // 去掉 -s 標(biāo)志。
CFLAGS  =-Wall -O -g -fomit-frame-pointer \             // 添加 -g 標(biāo)志。
    進(jìn)入內(nèi)核源代碼目錄后,利用find命令我們可以找到以下所有需要修改的Makefile文件:
[root@plinux linux-0.11]# find ./ -name Makefile
./fs/Makefile
./kernel/Makefile
./kernel/chr_drv/Makefile
./kernel/math/Makefile
./kernel/blk_drv/Makefile
./lib/Makefile
./Makefile
./mm/Makefile
[root@plinux linux-0.11]#
   另外,由于此時(shí)編譯出的內(nèi)核代碼模塊中含有調(diào)試信息,因此system模塊大小可能會(huì)超過(guò)寫(xiě)入內(nèi)核代碼映像文件的默認(rèn)最大值SYSSIZE =0x3000(定義在boot/bootsect.s文件第6行)。我們可以按以下方法修改源代碼根目錄中的Makefile文件中產(chǎn)生Image文件的規(guī)則,即把內(nèi)核代碼模塊system中的符號(hào)信息去掉后再寫(xiě)入Image文件中,而原始帶符號(hào)信息的system模塊保留用作gdb調(diào)試器使用。注意,目標(biāo)的實(shí)現(xiàn)命令需要以一個(gè)制表符(TAB)作為一行的開(kāi)始。
Image: boot/bootsect boot/setup tools/system tools/build
        cp -f tools/system system.tmp
        strip system.tmp
        tools/build boot/bootsect boot/setup system.tmp $(ROOT_DEV) $(SWAP_DEV) > Image
        rm -f system.tmp
        sync
    當(dāng)然,我們也可以把boot/bootsect.s和tools/build.c中的SYSSIZE值修改成0x8000來(lái)處理這種情況。

14.13.3 調(diào)試方法和步驟
    下面我們根據(jù)在現(xiàn)代Linux系統(tǒng)(例如RedHat 9)系統(tǒng)上和運(yùn)行在Bochs中Linux 0.11系統(tǒng)上編譯出的內(nèi)核代碼分別來(lái)說(shuō)明調(diào)試方法和步驟。
1 調(diào)試現(xiàn)代Linux系統(tǒng)上編譯出的Linux 0.11內(nèi)核
   假設(shè)我們的Linux0.11內(nèi)核源代碼根目錄是linux-rh9-gdb/,則我們首先在該目錄中按照上面方法修改所有Makefile文件,然后在linux-rh9-gdb/目錄下創(chuàng)建一個(gè)bochs運(yùn)行配置文件并下載一個(gè)配套使用的根文件系統(tǒng)映像文件。我們可以直接從網(wǎng)站下載已經(jīng)設(shè)置好的如下軟件包來(lái)做實(shí)驗(yàn):
    [url]http:///Linux.old/bochs/linux-0.11-gdb-rh9-050619.tar.gz[/url]
    使用命令“tar zxvf linux-gdb-rh9-050619.tar.gz”解開(kāi)這個(gè)軟件包后,可以看到其中包含以下幾個(gè)文件和目錄:
[root@plinux linux-gdb-rh9]# ll
total 1600
-rw-r--r--    1 root     root        18055 Jun 18 15:07 bochsrc-fd1-gdb.bxrc
drwxr-xr-x   10 root     root         4096 Jun 18 22:55 linux
-rw-r--r--    1 root     root      1474560 Jun 18 20:21 rootimage-0.11-for-orig
-rwxr-xr-x    1 root     root           35 Jun 18 16:54 run
[root@plinux linux--gdb-rh9]#
這里的bochs配置文件與其他Linux 0.11配置文件的主要區(qū)別是在文件頭部添加有以下一行內(nèi)容,表示當(dāng)bochs使用這個(gè)配置文件運(yùn)行時(shí)將在本地網(wǎng)絡(luò)端口1234上偵聽(tīng)gdb調(diào)試器的命令:
gdbstub: enabled=1, port=1234, text_base=0, data_base=0, bss_base=0
運(yùn)行這個(gè)實(shí)驗(yàn)的基本步驟如下:
(1).啟動(dòng)X window系統(tǒng)后打開(kāi)兩個(gè)終端窗口;
(2).在一個(gè)窗口中,把工作目錄切換進(jìn)linux-gdb-rh9/目錄中,并運(yùn)行程序“./run”,此時(shí)該窗口中會(huì)顯示一條等待gdb來(lái)連接的信息:“Wait for gdb connection on localhost:1234”,并且系統(tǒng)會(huì)創(chuàng)建一個(gè)Bochs主窗口(此時(shí)無(wú)內(nèi)容);
(3).在另一個(gè)窗口中,我們把工作目錄切換到內(nèi)核源代碼目錄中l(wèi)inux-gdb-rh9/linux/,并運(yùn)行命令:“gdb tools/system”;
(4).在運(yùn)行g(shù)db的窗口中鍵入命令“break main”和“target remote localhost:1234”,此時(shí)gdb會(huì)顯示已經(jīng)連接到Bochs的信息;
(5).在gdb環(huán)境中再執(zhí)行命令“cont”,稍過(guò)一會(huì)gdb會(huì)顯示程序停止在init/main.c的main()函數(shù)處。
下面是運(yùn)行g(shù)db和在其中執(zhí)行的一些命令示例。
[root@plinux linux]# gdb tools/system        
GNU gdb Red Hat Linux (5.3post-0.20021129.18rh)
Copyright 2003 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu"...
(gdb) break main               
Breakpoint 1 at 0x6621: file init/main.c, line 110.
(gdb) target remote localhost:1234
Remote debugging using localhost:1234
0x0000fff0 in sys_mkdir (pathname=0x0, mode=0) at namei.c:481
481     namei.c: No such file or directory.
        in namei.c
(gdb) cont                        
Continuing.
Breakpoint 1, main () at init/main.c:110    
110             ROOT_DEV = ORIG_ROOT_DEV;
(gdb) list                                  
105     {                       /* The startup routine assumes (well, ...) this */
106     /*
107      * Interrupts are still disabled. Do necessary setups, then
108      * enable them
109      */
110             ROOT_DEV = ORIG_ROOT_DEV;
111             drive_info = DRIVE_INFO;
112             memory_end = (1<<20) + (EXT_MEM_K<<10);
113             memory_end &= 0xfffff000;
114             if (memory_end > 16*1024*1024)
(gdb) next 
111             drive_info = DRIVE_INFO;
(gdb) next 
112             memory_end = (1<<20) + (EXT_MEM_K<<10);
(gdb) print /x ROOT_DEV                      
$3 = 0x21d                                   
(gdb) quit                                   
The program is running.  Exit anyway? (y or n) y
[root@plinux linux]#

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多