文章詳情頁(yè)
UNIX系統(tǒng)開(kāi)發(fā)-SDB調(diào)試技術(shù)
瀏覽:116日期:2024-06-23 09:59:37
我們說(shuō)程序調(diào)試的主要目的是觀察變量的變化情況。但如果程序就一直不停地運(yùn)行直至它終止或出錯(cuò)時(shí)才停下來(lái)的話,將沒(méi)有機(jī)會(huì)去觀察任何變量。因此,如何有效地控制程序中各語(yǔ)句的執(zhí)行,使之在適當(dāng)?shù)臅r(shí)候暫停下來(lái),待調(diào)試人員在顯示或設(shè)置了某些存儲(chǔ)單元的值之后再?gòu)耐O碌牡胤嚼^續(xù)執(zhí)行下去,是調(diào)試程序應(yīng)具有的一項(xiàng)基本功能。在這一節(jié)中我們就來(lái)具體介紹如何控制程序的運(yùn)行。 對(duì)程序執(zhí)行控制的第一個(gè)問(wèn)題是設(shè)置斷點(diǎn)。一個(gè)斷點(diǎn)實(shí)際上就是程序中某行語(yǔ)句。當(dāng)程序執(zhí)行到這條語(yǔ)句時(shí)控制會(huì)重復(fù)返回到sdb,由此提供給用戶進(jìn)行其他操作,如顯示變量值的機(jī)會(huì)。 1.斷點(diǎn)的設(shè)置和刪除 在sdb中設(shè)置斷點(diǎn)的方法比較多。但基本是b命令的變種。例如,我們可以使用如下語(yǔ)句在main()函數(shù)的第一個(gè)可執(zhí)行(非變量定義這類(lèi)語(yǔ)句)設(shè)置一個(gè)斷點(diǎn):* main:b 也可以直接用行號(hào)來(lái)設(shè)置斷點(diǎn)。例如,在myprog.c中,第10行是main()函數(shù)中的第一個(gè)可執(zhí)行語(yǔ)句,則使用如下命令也能達(dá)到同樣的效果:* 10b 注意這是在myprog.c為當(dāng)前文件的情況下進(jìn)行的。 如果直接輸入:* b 命令,則可將當(dāng)前行設(shè)成是一個(gè)斷點(diǎn)。但是若當(dāng)前行不是一個(gè)可執(zhí)行語(yǔ)句,那么sdb將把當(dāng)前行之后的第一個(gè)可執(zhí)行語(yǔ)句處設(shè)置一個(gè)斷點(diǎn)。在設(shè)置完斷點(diǎn)之后,為了解程序中設(shè)置有哪些斷點(diǎn),可以使用B命令:* B 0x80483f0 myprog.c:10 main+0x8 0x80483f7 myprog.c:11 main+0xf 0x8048407 myprog.c:12 main+0xlf 0x8048440 myprog.c:9 TestInput 0x8048447 myprog.c:10 TestInput+ 0x7 0x804482 myprog.c:13 TestInput+ 0x42 在設(shè)置完斷點(diǎn)之后要將其刪除,可以使用d命令。如:* main:d sdb將把在main()函數(shù)中設(shè)置的第一個(gè)可執(zhí)行行上的斷點(diǎn)刪除。如果直接使用d命令,sdb將逐個(gè)列出所有斷點(diǎn)并詢問(wèn)用戶是否刪除之。回答y斷點(diǎn)將被刪除。使用D命令則可刪除程序中設(shè)置的所有斷點(diǎn)。 2.sdb中啟動(dòng)程序的運(yùn)行 在設(shè)置好所需的斷點(diǎn)之后我們就可以重新啟動(dòng)程序的運(yùn)行了。這可以使用r命令。如:* r 111 2 BREAKPOINT process 554 function main() in myprog.c 10: for(i=1;i<argc:i++) * sdb將在main()函數(shù)中設(shè)置第一個(gè)斷點(diǎn)處停下來(lái)并顯示該行的語(yǔ)句。r后面給出的是傳給可執(zhí)行程序myprog的兩個(gè)參數(shù)。因此上述命令同在shell提示符下輸入: $ myrprog 111 2 是相同的。不同的只是在sdb中程序的執(zhí)行會(huì)在斷點(diǎn)處停下來(lái)。 如果只輸入 * r 命令,sdb使用最近一次執(zhí)行調(diào)試程序時(shí)給它提供的參數(shù)來(lái)啟動(dòng)之。如果想不帶任何參數(shù)來(lái)重新啟動(dòng)程序的運(yùn)行,可使用 * R 命令。 3.控制程序的單步或者連續(xù)執(zhí)行 在用r(R)命令啟動(dòng)程序的運(yùn)行之后,sdb將在第一個(gè)斷點(diǎn)處暫停程序的運(yùn)行。此時(shí)斷點(diǎn)行成為當(dāng)前行,但并未被執(zhí)行。此時(shí)我們可以在sdb的星號(hào)(*)提示符下輸入前面已介紹過(guò)的或后面將要介紹的各種命令。當(dāng)然最重要的是顯示那些關(guān)鍵變量的值,以了解程序的運(yùn)行情況。在這之后便可以繼續(xù)程序的執(zhí)行。繼續(xù)執(zhí)行有兩種方式。一種是單步方式,即逐條語(yǔ)句執(zhí)行。這可以使用S命令完成: * s STEPPED process 584 function main() in myprog.c 14: printf('The %dth value '%s' tis BAD!n',i,argv[i]); * sdb在執(zhí)行完當(dāng)前語(yǔ)句之后,將當(dāng)前行后移一行并顯示出其代碼。對(duì)于用戶自定義的函數(shù)調(diào)用,S命令并不將其當(dāng)成是一條語(yǔ)句,此時(shí)它將指示sdb進(jìn)入該函數(shù)(使之成為當(dāng)前函數(shù))。如我們可以接著上面輸入下列命令: * s STEPPED process 584 function main() in myprog.c 11: if(TestInput(argv[i])== TESTOK) * s BREAKPOINT process 594 function main() in myprog.c 11: if(TestInput(argv[i])==TESTOK) * s BREAKPOINT process 584 function TestInput() in myfunc.c 9: {while (* ValueInput)} * s 也能讓sdb將用戶自定義的函數(shù)調(diào)用,當(dāng)成是一條普通語(yǔ)句而不進(jìn)入此函數(shù)的定義。此時(shí)可以在那些包含有用戶自定義函數(shù)調(diào)用的行,使用S命令以執(zhí)行之。s 和S命令都可以接收一個(gè)指明待執(zhí)行的語(yǔ)句數(shù)目的參數(shù)。例如: * s 2 使sdb執(zhí)行當(dāng)前行及其下那行語(yǔ)句,然后當(dāng)前行之下的第2行將成為新的當(dāng)前行。注意當(dāng)使用s 或S時(shí),如果sdb遇上一個(gè)未加-g選項(xiàng)編譯的用戶自定義函數(shù),那么執(zhí)行將繼續(xù)直到一個(gè)帶-g 選項(xiàng)編譯的函數(shù)為止。 控制程序執(zhí)行的第二種是使用c或C命令。一個(gè)最簡(jiǎn)單的c命令將使sdb從當(dāng)前行把程序執(zhí)行到下一個(gè)斷點(diǎn)處。在c命令中還可以臨時(shí)設(shè)置“斷點(diǎn)”。例如: * 8c 將使sdb在第8行上設(shè)置一個(gè)斷點(diǎn)并使程序從當(dāng)前行執(zhí)行至該斷點(diǎn)處后停下來(lái),然后將此斷點(diǎn)自動(dòng)刪除并等待用戶輸入其他命令。 在c命令中還可以指定在繼續(xù)執(zhí)行時(shí)后面第幾個(gè)斷點(diǎn)處停下來(lái)。例如: * c 2 將使sdb從當(dāng)前行開(kāi)始執(zhí)行,直到當(dāng)前行之后的第2個(gè)斷點(diǎn)為止。一般的:* c 命令實(shí)際上相當(dāng)于:* c 1 C命令的作用及用法同c基本上是相同的。只不過(guò)此時(shí)sdb將進(jìn)程收到的終止信號(hào)傳給該進(jìn)程進(jìn)行處理。這對(duì)于調(diào)試有軟中斷處理的進(jìn)程是很有用的。但sdb并不是將進(jìn)程所收到的所有信號(hào)都傳送給進(jìn)程進(jìn)行處理。要傳遞的信號(hào)可在sdb的命令行中用-s選項(xiàng)指定。 我們可以用g命令來(lái)告訴sdb在給定的行開(kāi)始繼續(xù)程序的執(zhí)行: * 6g 此命令使sdb在當(dāng)前文件的第6行處恢復(fù)執(zhí)行。而:* 6g2 使sdb在當(dāng)前文件的第6行恢復(fù)執(zhí)行并跳過(guò)兩個(gè)斷點(diǎn)。但在使用g命令時(shí)必須小心。如果此命令跳過(guò)了那些必須得初始化語(yǔ)句,或者進(jìn)程的執(zhí)行被恢復(fù)到某個(gè)并不終止進(jìn)程的函數(shù)中,此時(shí)都將會(huì)是程序的執(zhí)行出現(xiàn)人為的差錯(cuò)。一般而言,除非能夠確信所跳過(guò)的代碼段是不正確的代碼,不要輕易使用g命令。 4. 關(guān)聯(lián)命令 我們可以告訴sdb在使用到某種情況下暫停下來(lái),完成某些操作之后繼續(xù)執(zhí)行。例如: * 7b t; i/;c 將使得sdb在當(dāng)前文件的第7行設(shè)置一個(gè)斷點(diǎn),然后每當(dāng)遇到該斷點(diǎn)時(shí)都顯示函數(shù)調(diào)用棧(t)、變量i的值(i/),并繼續(xù)程序的執(zhí)行(c)。 上述命令的一種變化形式是a(Announce命令)。例如: * FunctionName:a 將使得sdb在程序執(zhí)行過(guò)程中每當(dāng)函數(shù)FunctionName被調(diào)用時(shí)即顯示其函數(shù)名和參數(shù)值。而命令: * FunctionName:6a 將使得sdb在函數(shù)FunctionName中的第6行每次被執(zhí)行時(shí)都將其顯示出來(lái)。 5.函數(shù)調(diào)用 sdb能夠調(diào)用程序中用戶自定義的任何函數(shù)。這種功能對(duì)于下面兩種情況可能比較有用: 在需要用各種不同的參數(shù)對(duì)函數(shù)進(jìn)行測(cè)試。 用用戶自己定義的一個(gè)函數(shù)來(lái)顯示程序中的某些數(shù)據(jù)。 不論是何種情況,我們均可以用如下命令來(lái)進(jìn)行函數(shù)調(diào)用: * FunctionName(Arg1,Arg2,....) 或 * FunctionName(Arg1,Arg2,....)/m 在第一種用法下,sdb只是簡(jiǎn)單地執(zhí)行指定的函數(shù)。在第二種用法下,sdb將在執(zhí)行指定的函數(shù)之后顯示返回值。此值一般將按十進(jìn)制方式顯示,除非指定了另外的顯示格式。 提供給函數(shù)的參數(shù)可以是寄存器名、整數(shù)、浮點(diǎn)數(shù)、字符、字符串常量或是其他局部當(dāng)前函數(shù),或者是當(dāng)前函數(shù)可以訪問(wèn)的變量。 6.變量的監(jiān)視 sdb提供了一種被成為“觀察點(diǎn)”(Watch)的機(jī)制。借此機(jī)制,我們可以監(jiān)視變量值得變化或某些地址的內(nèi)容的變化。例如: * i $m 可用于設(shè)置對(duì)某個(gè)變量的觀察點(diǎn)。此處變量i為被監(jiān)視的變量。而用: * 0x00400000:m 則可將地址0x00400000 處設(shè)置成觀察點(diǎn),而0x00400000將成為被監(jiān)視的地址。 在設(shè)置了觀察點(diǎn)之后,sdb會(huì)同處理S命令一樣開(kāi)始程序的單步執(zhí)行,并在變量的值或指定地址單元的內(nèi)容被改變時(shí)停止程序的執(zhí)行。由于變量值的改變或地址內(nèi)容的變化,或者其他什么原因而使程序的執(zhí)行中止,包括因?yàn)橛龅綌帱c(diǎn)而使程序停止的情形,都將使得所設(shè)置的觀察點(diǎn)被sdb自動(dòng)刪掉。被觀察的變量必須是當(dāng)前函數(shù)的局部變量或者是當(dāng)前函數(shù)所能夠訪問(wèn)的變量。 其他命令 除了上面介紹的五類(lèi)主要命令之外,sdb還支持其他一些命令。使用這些命令,可以完成其他一些輔助性的工作。分別介紹如下。 . !Shell Command 此命令可以使sdb去執(zhí)行指定的Shell Command。這里Shell Command是一個(gè)合法命令。例如可以輸入: * ! ls -l sdb將執(zhí)行指定的ls -l 命令,并將其輸出顯示出來(lái)。 使用: * ! sh 能夠生成一個(gè)新的Shell進(jìn)程。在此新的Shell中可以完成某些工作,然后用exit命令返回到sdb中。 <FileName 指示sdb從文件FileName中讀取sdb調(diào)試命令,并且逐個(gè)執(zhí)行之。 'SomeString 指示sdb顯示出某個(gè)字符串。常用此命令給出某些提示信息, k 此命令將使當(dāng)前對(duì)程序的調(diào)試終止,之后仍可用r命令重新啟動(dòng)被調(diào)試的程序。如: * k 1111:killed * 這里1111是被調(diào)試進(jìn)程的進(jìn)程號(hào)。 * q 此命令將使sdb停止其自身的運(yùn)行而返回至原Shell提示符下。在調(diào)試完程序之后一般都要使用此命令。
標(biāo)簽:
Unix系統(tǒng)
排行榜
