有人問我在接受採訪時你怎麼能使用GDB C程序調試段錯誤多個文件。我如何找到分段錯誤使用GDB
我告訴他們,我們可以編譯我們的程序與-g
選項,因爲它添加調試信息到二進制文件,讀取核心轉儲文件,但後來面試官告訴我,如果他我們有3個文件一起編譯,但其中一人造成分段錯誤,那麼我們如何在GDB中進行調試?
有人問我在接受採訪時你怎麼能使用GDB C程序調試段錯誤多個文件。我如何找到分段錯誤使用GDB
我告訴他們,我們可以編譯我們的程序與-g
選項,因爲它添加調試信息到二進制文件,讀取核心轉儲文件,但後來面試官告訴我,如果他我們有3個文件一起編譯,但其中一人造成分段錯誤,那麼我們如何在GDB中進行調試?
聽起來好像他們正在尋找設定,讓你可以當它運行步執行代碼,你可以使用命令行版本做,或者我認爲你可以得到GDB的GUI。
如果你是Linux下工作更輕鬆的方式找到段錯誤是使用名爲Valgrind的工具:http://valgrind.org/。
你只需要使用-g標誌編譯代碼,然後運行./valgrind。
然後你就會知道到底在功能和哪一行代碼有錯誤,未初始化內存/存儲器中讀出分配的空間或某事的。
$ gcc -ggdb s1.c s2.c s3.c -o myprog
$ gdb myprog
(gdb) run --arg1 --arg2
GDB將運行程序爲正常,當分割故障發生GDB會回落到其迅速,這將是幾乎相同的,與一個核心文件運行GDB。主要的不同之處在於,當程序在GDB中崩潰時,您無法使用核心文件進行打印。 (例如,您可以使用print
來調用程序中的某些功能。)
您也可以使用gdb --pid <the programs pid>
附加到已經運行的程序。
要麼與核心文件或與上述方法之一,當你有崩潰後GDB提示符鍵入backtrace
(或bt
的簡稱)和GDB將告訴你在堆棧在崩潰的時間,包括每個調用的文件名和行號以及當前正在執行的行。
我以爲我們應該用「gcc -g」,什麼意思是「gcc -ggdb」 –
[手冊](https://gcc.gnu.org/onlinedocs/gcc-4.9.2/gcc/Debugging-Options .html#Debugging-Options)解釋... -ggdb可以爲GDB生成額外的信息,-g不會。如果你打算使用GDB,你應該使用-ggdb。 – SoapBox
謝謝SoapBox :) –
您只需運行gdb下的程序,並與漁獲SIGSEGV調試和告訴你,故障線路和指令。然後,您只需檢查變量和/或寄存器值以查看錯誤。通常它是一個流氓指針值,試圖用GDB訪問它會給出錯誤,所以很容易。
是的,使用-g重新編譯所有內容將會有所幫助。面試官可能想讓你描述一下你如何弄清楚哪個文件有問題(gdb只是告訴你什麼時候捕捉到信號),然後用調試信息重新編譯那個文件。如果有20,000個可能有用的源文件,但有3或4個文件,那有什麼意義?即使是更大的項目,你通常最終還是會通過10個函數和5個文件來追蹤不良指針,所以再一次,有什麼意義呢?調試信息在運行時不會花費任何費用,儘管它會在安裝中花費磁盤空間。
爲什麼downvote? – ams
通過給GCC文件名 編譯正常方式的代碼,你會得到一個.out
文件,啓動運行,並通過在另一個窗口類型gdb
給ps -aef | grep filename.out
獲得進程ID,輸入,GDB提示透露了一些內幕attach processid
(processid你會從上面的命令中獲得),給c
繼續。一旦執行結束,在gdb中給出「bt」,你將得到分割正在發生的地方。
可以用gdb
$ gdb <exec name >
$ r //run the pgm
$ where
$ f <1> <0> //to view the function n variables
$ list
$ p <variable>
除非我真的誤解你的要求使用以下步驟來調試段錯誤,你還是會編譯它們全部用-g和調試的完全一樣辦法。 –
我也給了他們同樣的解決方案,但他們根本沒有留下深刻的印象,他們認爲它不會告訴我們導致分段錯誤的確切文件名 –
其實,在我看到的所有面試問題中,這個實際上是非常明智的。有意義檢查開發人員是否知道如何使用相應平臺上的任何調試器。 –