Linux學習 gdb除錯(指標的指標)

2022-05-05 07:15:13 字數 2793 閱讀 2650

昨天遇到乙個很奇怪的問題,如下:

按照理論,最後*p的值應該是99,不知為什麼是15了,所以今天記錄用gdb除錯的過程,並熟悉gdb的使用。

(除錯過程參考: 

開始:1.

2.(用list從第1行開始列出原始碼)

3.(一次只列10行,如果要從第11行開始繼續列源**可以輸入list)

4.(也可以什麼都不輸直接敲回車,gdb提供了乙個很方便的功能,在提示符下直接敲回車表示重複上一條命令。)

5.(gdb的很多常用命令有簡寫形式,例如list命令可以寫成l,要列乙個函式的源**也可以用函式名做引數:)

6.(退出gdb環境)

7.(現在將niuke.cpp改名,然後gdb就列不出原始碼了)

說明:gcc-g選項並不是把源**嵌入到可執行檔案中的,在除錯時也需要原始檔。

8.(原始碼檔案恢復,重新開始)

gdb停在main函式中變數定義之後的第一條語句處等待我們發命令,gdb列出的這條語句是即將執行的下一條語句。

9.(我們可以用next命令(簡寫為n)控制這些語句一條一條地執行)

說明:用n函式f()中的結果一下就列印出來了

10.(現在用start重新開始,用step命令(簡寫s)進入f()中去跟蹤執行)

現在進入了f()函式。

11.(在函式中有幾種檢視狀態的辦法,backtrace命令(簡寫為bt)可以檢視函式呼叫的棧幀)

可見當前f()是被main()呼叫的,傳入指標p傳給ret=0xbfffee94

12.(檢視當前f()函式內區域性變數的值i locals 或者info locals)

13.(如果想檢視main函式當前區域性變數的值也可以做到,先用frame命令(簡寫為f)選擇1號棧幀然後再檢視區域性變數,i locals, info locals)

14.(繼續執行,然後用p+變數名檢視變數的值)

這裡......$5,$6,$7,$8......分別儲存了檢視的中間值:

未執行*ret = &a時:

ret: 0xbfffee94(為&p)  *ret:0xbfffef54(p)  **ret:-1073745577

執行*ret = &a後:

ret: 0xbfffee94  *ret:0xbfffee68 = &a:0xbfffee68(值為99)  **ret:99(等於a)

15.(finish命令讓程式一直執行到當前函式結束) 

返回值是ret=0xbfffee94(&p)

16.(現在繼續執行)

注意:a &p address : 0xbfffee94(&p未改變)  a p address : 0xbfffee68(與&a相同)a *p value   : 15(奇怪的地方,為什麼不是99)

17.(換一種思路:在執行 cout << "a &p address : " << &p << endl; 之前直接檢視*p)

這裡可以看到*p=99,是正確的,位址也與上面相同

18.(繼續除錯)

這裡發現*p=15,被改變了。

也就是說:在執行cout << "a &p address : " << &p << endl;後, *p的值被改變了,從99變為15了。

19.(連續輸出兩次*p)

這次發現第一次輸出結果正常,第二次輸出結果出錯,那為什麼呢?為什麼呢?????

20.(知道原因了)

說明:a是乙個區域性變數,&a在f()執行完後就被系統**了。f()中ret = &a 這一步,使得p=&a,所以最後p輸出不對。
修改後:

這裡終於正確了。

ps:前面一種情況,棧被系統**,但是仍能輸出一次99,我猜可能是系統還沒來的及**。。。

pss:指標太容易出錯了。。 

Linux下gdb除錯學習

以test.cpp為例 include include int main std cout下面是gcc g 常用編譯選項,我們的可執行檔案要能夠被gdb除錯,必須在編譯時加上除錯資訊,也即是加上 g選項 完整命令如下 g g test.cpp o test 執行gdb test 進入gdb除錯 種種...

gdb除錯學習

一般來說,gdb主要幫忙你完成下面四個方面的功能 1 啟動你的程式,可以按照你的自定義的要求隨心所欲的執行程式。2 可讓被除錯的程式在你所指定的調置的斷點處停住。斷點可以是條件表示式 3 當程式被停住時,可以檢查此時你的程式中所發生的事。4 動態的改變你程式的執行環境。除錯的程式如下 root lo...

gdb除錯學習

gdb是乙個由gnu開源組織發布的,unix linux作業系統下的,基於命令列,功能強大的程式除錯工具。可以用來除錯c,c 程式。在今天驗收實驗時發生特別尷尬的事情,由於在編譯.c檔案的時候沒有加 g選項,所以一直無法用gdb除錯程式,所以在總結gdb之前先來看看gcc在編譯時的引數。a.常規選項...