監視點是指示gdb每當某個表示式改變了只,就暫停執行指令。如watch i它會使得每當i改變值時gdb就暫停。也可以使得watch後面的更複雜如:watch (i | j > (2) && i > 24) && strlen(name)> 6這是將監視點看作「附加」在表示式上,當表示式的值改變時,gdb會暫停程式的執行。
斷點與源**中的乙個位置關聯,監視點則是對與記憶體,當變數不存在時,gdb自動刪除監視點。
監視點的使用形式如watch var,gdb實際上在var的記憶體位置改變值時中斷。
監視點使用的最多的地方是對於指標的監視,對於c、c++這樣的指標型語言,可能對指標進行修改,這是時候watch可以有效的監視指標。形如:p =&y; p = &x監視y可以知道值是在何處被修改的,防止不必要的錯誤。
對於c這樣的語言,在工程中少不了使用結構體,但是我們在gdb除錯的時候每次都比較麻煩,為了列印結構體裡面的變數,我們要重複的輸入ptempstruct->value的表示式。不過還好有簡單的方法如下。
1、 print *tmp:tmp是指標結構,tmp指向結構體,因此*tmp是這個結構體本身,這樣能輸出結構體的所有變數。
2、 使用gdb的display命令:如果知道會在每次遇到斷點時鍵入這個命令,那麼使用gdb的display命令(簡寫disp),這個命令要求gdb在執行中每次有暫停(由於有斷點,使用next、step命令等)時就輸出指定條目。
3、 使用gdb的commands命令,在給定點上時檢視子結點的值。下面是對資料結構中的二叉樹的輸出。
commands 1
p tmp->val
if (tmp->left != 0)
ptmp->left->val;
else
printf「%s\n」 「none」
endif (tmp ->right != 0)
ptmp->right->val;
else
printf「%s\n」 「none」
endend
4、 使用gdb的call,可以對現有**進行呼叫函式,除錯中的乙個常見方法是隔離出現問題的第乙個資料項。在上下文中,可以通過每次完成對insert的呼叫時輸出整個樹來完成這件事情。
command 2
printf 「*******current tree *********」
call printtree(root) printtree是我們自己寫的函式
endddd中可以使用ddd –separate bintree來分離視窗,為了使除錯更為方便和直觀。
在程式設計中我們常常會使用動態陣列,例如:
int x[25];
print x
int *x;
x = (int *)malloc(25 * sizeof(int));
p x 這時只會列印x[0]的值。怎樣才能輸出x陣列中的所有值呢?
解決方法:在gdb中,可以通過建立乙個人工陣列(artificial array)來解決這個問題。如:
int *x;
main()
可以使用p *x@25可以將動態陣列裡面的資料全部列印出來。
人工陣列的形式:*pointer@number-of-elements,gdb還允許在適當的時候使用型別強制轉換,比如:p (int[25])*x進行列印。
對於c++來說,如果使用了物件來建立二叉樹則在node中不能使用p *root來列印,這是會報錯:can notaccess memory at address,用print列印也得換一種形式如p *node::root這樣才能列印出來,因為root是class node的物件。
《軟體除錯藝術》讀後感三
在談這個問題前我們有沒有遇到過這樣的場景,每次要修改一次 然後make,之後gdb除錯,然後出gdb中quit,再次修改再次make再次gdb進入再次quit一直重複著乙個工作。那有沒有方法可以避免這樣的重複事情呢?畢竟程式設計師對這種重複的步驟很反感。在實際專案中,乙個專案不可能一天就能完成,有時...
《軟體除錯藝術》讀後感四
只有符合某種條件時才在斷點處停止。類似於監視點的工作方式,每當該變數的值發生變化時,監視點都會中斷。條件斷點只會在懷疑有問題的 處當變數呈現該懷疑值時才中斷。設定條件斷點 breakbreak args if conditon 如 break if i 700 condition 6999 條件可以...
《軟體除錯藝術》讀後感六
在gdb中,可以通過呼叫info locals命令得到當前桟幀中的所有區域性變數的值的列表。在有些情況下,可能希望檢查給定位址的記憶體,而不是通過變數的名稱。gdb為這種目的提供x命令。print和display的高階選項,print和display命令允許指定可選的格式。例如p x y,這樣會以十...