部分觀點(diǎn)可能過于激進(jìn),讀者自行取舍。盡管我認(rèn)為程序是寫出來(lái)的,不是調(diào)出來(lái)的(和市場(chǎng)上的觀點(diǎn)正好相反),優(yōu)質(zhì)的程序應(yīng)該在模塊設(shè)計(jì)和實(shí)現(xiàn)時(shí)應(yīng)保證不出現(xiàn)什么bug。這當(dāng)然只是理想情況,還得取決于個(gè)人水平。程序應(yīng)在實(shí)現(xiàn)階段得到最大保證,而不是過度依賴調(diào)試器。一個(gè)徹底的反調(diào)試派,據(jù)說(shuō)真正的高手會(huì)在cpu旁放一顆爆米花:)轉(zhuǎn)載請(qǐng)保留原創(chuàng):http://m.shnenglu.com/jinglexy,MSN & Email:jinglexy at yahoo dot com dot cn
如果系統(tǒng)處于仿真的初期節(jié)點(diǎn),例如操作系統(tǒng)的初始化,調(diào)試還是很有必要的。這里是我在linux環(huán)境調(diào)試操作系統(tǒng)的相關(guān)工具,os開發(fā)者可參考,歡迎指正:)
(1)工具安裝:
linux安裝:bochs-2.3,insight-6.6,gcc-3.4(使用g++和as(binutils包中))
windows安裝:Xmanager Enterprise2.1
因?yàn)榫W(wǎng)管沒有l(wèi)otus和clearcase在linux系統(tǒng)下的支持,所以只好用兩個(gè)操作系統(tǒng)了。這樣也比較好,一個(gè)用于program,一個(gè)用于調(diào)試,畢竟bochs挺耗cpu的,就讓她干活好了。
bochs安裝:./configure --with-all-libs --enable-vbe --enable-gdb-stub && make && make install
insight-6.6安裝:包含了tck/tk,gdb-6.6,bfd等工具,使用insight時(shí)最好這樣設(shè)置環(huán)境變量:
export LC_ALL=en_US
否則運(yùn)行時(shí)可能會(huì)報(bào)錯(cuò):
Tcl_Init failed: can't read "env(TCL_LIBRARY)": no such variable
配置xserver用于遠(yuǎn)程訪問Linux圖形界面,這樣可以在windows上通過ssh執(zhí)行l(wèi)inux的圖形界面程序。
(2)相關(guān)文件:
bochs配置文件添加如下節(jié):
gdbstub: enabled=1, port=1234, text_base=0, data_base=0, bss_base=0
gdb調(diào)試腳本:
gdb的命令集可以寫入到一個(gè)文件中去,這樣避免了在啟動(dòng)時(shí)輸入一大堆命令,100%鼠標(biāo)操作?faint
保存所有命令到一個(gè)文件,每行一個(gè)命令,如下:
file ./vmjinix
target remote 127.0.0.1:1234
dir ./arch/i386
dir ./init
dir ./kernel
dir ./drivers
dir ./drivers/video
dir ./drivers/video/console
show dir
break start_kernel
continue
list 0
gdb和gdb前端執(zhí)行如下:
gdb -q -x gdb.command
insight -q -x gdb.command
其他腳本(磁盤自動(dòng)創(chuàng)建分區(qū),自動(dòng)安裝grub,拷貝內(nèi)核,及Makefile腳本),這些貼出來(lái)太長(zhǎng),花了好幾個(gè)小時(shí)寫好的,需要可以和我聯(lián)系(MSN & Email:jinglexy at yahoo dot com dot cn)
(3)調(diào)試方法
將內(nèi)核(jinix-1.2.1是我正在編寫的一個(gè)C++ 開源OS,歡迎參與)拷貝到linux主機(jī),配置samba共享,這樣可以在windows上開發(fā)(推薦使用slickedit 2007,哪位有l(wèi)inux上的2007版本可否發(fā)一個(gè)給我)。
使用xshell(ssh方式)登錄到linux主機(jī)上,編譯和調(diào)試都在這里了。
在ssh上執(zhí)行bochs -f bochsrc.txt.linux,
在ssh上執(zhí)行insight -q -x gdb.command
截圖如下:

匯編語(yǔ)言節(jié)點(diǎn)也可用使用bochs+gdb調(diào)試,在gdb斷點(diǎn)時(shí)候執(zhí)行:
disassemble $pc $pc+100(從當(dāng)前斷點(diǎn)處反匯編100字節(jié))
需要注意的是,在os的匯編初始化的前期階段,分頁(yè)機(jī)制往往未開啟,符號(hào)和地址不能一一對(duì)應(yīng),
這個(gè)時(shí)候不能進(jìn)行源碼級(jí)匯編調(diào)試,只能用最即便的反匯編調(diào)試了。
bochs-2.3中好像有個(gè)bug沒有解決,nexti執(zhí)行和stepi在call的時(shí)候居然一樣,如果要斷點(diǎn)到指定行,可以使用物理地址斷點(diǎn)。
(4)文章會(huì)不斷更新,如有什么好的想法可以在原博客討論:
http://m.shnenglu.com/jinglexy
(5)整理的一份常用gdb指令
x /4wx ds:0x1234 x是線性地址空間
xp /4wx 0x1234 xp是物理地址空間
backtrace
print variable 打印變量值
print variable@10 打印變量后面的10個(gè)整數(shù)值
set variable=2 賦值
whatis variable 顯示變量類型
ptype variable 顯示數(shù)據(jù)結(jié)構(gòu)(變量類型加強(qiáng)版)
斷點(diǎn)類型:
break init_kernel.cpp:start_kernel 斷點(diǎn)在文件的函數(shù)
break init_kernel.cpp:101 斷點(diǎn)在文件的101行
break init_kernel.cpp:101 if var==100 條件斷點(diǎn)
break *0xc0102030
info break 查看所有斷點(diǎn)
delete breakpoint 3
delete breakpoint 刪除所有斷點(diǎn)
isable breakpoint 2
enable breakpoint 2
search string1 搜索字符串,從list結(jié)束行開始
reverse-search string1 方向搜索
set history expansion on 使用歷史命令
clear 刪除剛才停止處的斷點(diǎn)
continue 從斷點(diǎn)開始繼續(xù)執(zhí)行
info break 顯示當(dāng)前斷點(diǎn)清單,包括到達(dá)斷點(diǎn)處的次數(shù)等
info files 顯示被調(diào)試文件的詳細(xì)信息
info func 顯示所有的函數(shù)名稱
info local 顯示當(dāng)函數(shù)中的局部變量信息
info prog 顯示被調(diào)試程序的執(zhí)行狀態(tài)
info var 顯示所有的全局和靜態(tài)變量名稱
info all
run
continue
step, next, stepi, nexti i后綴表示執(zhí)行一條匯編指令
/*********************************************************************************
格式說(shuō)明 /
/*********************************************************************************
x /nuf addr檢查位于線性地址addr處的內(nèi)存內(nèi)容,若addr不指定,則默認(rèn)為下一個(gè)單元地址。
xp /nuf addr檢查位于物理地址addr處的內(nèi)存內(nèi)容。
其中的可選參數(shù)n、u和f的分別可為:
n欲顯示內(nèi)存單元的計(jì)數(shù)值,默認(rèn)值為1。
u表示單元大小,默認(rèn)選擇為'w':
b (Bytes)1字節(jié);
h (Halfwords)2字節(jié);
w (Words)4字節(jié);
g (Giantwords)8字節(jié)。
注意:這些縮略符與Intel的不同,主要是為了與GDB調(diào)試器的表示法一致。
f顯示格式,默認(rèn)選擇為'x':
x (hex)顯示為十六進(jìn)制數(shù)(默認(rèn)選擇);
d (decimal)顯示為十進(jìn)制數(shù);
u (unsigned)顯示成無(wú)符號(hào)十進(jìn)制數(shù);
o (octal)顯示成八進(jìn)制數(shù);
t (binary)顯示成二進(jìn)制數(shù)。
c (char)顯示字節(jié)代碼對(duì)應(yīng)的字符。若不是可顯示字符代碼,就直接顯示代碼。
*********************************************************************************/
說(shuō)明一下:bochs 和 insight本身單個(gè)執(zhí)行就非常慢,而且insight是通過ssh方式鏈接遠(yuǎn)程xserver執(zhí)行,所以速度巨慢,本文所述完全可以全部在linux上操作,不限于平臺(tái)。