GDB除錯段錯誤

2021-09-27 12:38:43 字數 3089 閱讀 9449

一、gdb的除錯命令。

c語言是:cc -g tst.c -o tst;c++是g++  -g -o (生成的檔案) file.cpp

c++除錯程式命令:gdb  file 啟動,羅列**行數ist 1,break (行數),info break,run(r)除錯執行,step(s)單步除錯,檢視變數 print(p) 變數名,檢視堆疊式bt,繼續除錯continue(c),退出程式q

二、core檔案的產生

當linux程式在執行過程中掛掉的時候,可能就出現core檔案。通過除錯core檔案就可以看出來程式在**那個位置掛掉了。會在指定的目錄下生成core檔案,core檔案時記憶體的映像並加入了除錯資訊,主要用來除錯

用以下命令來阻止系統生成core檔案:

ulimit -c 0

下面的命令可以檢查生成core檔案的選項是否開啟:

ulimit -a

該命令將顯示所有的使用者定製,其中選項-a代表「all」。

不產生core檔案原因,1、沒有足夠記憶體空間,2、禁用了core檔案的建立,3、設定乙個程序當前目錄沒有寫檔案的許可權

除錯core檔案

ulimit  -c  unlimited 表示要生成core檔案 不限制core檔案的大小

三、利用gdb來除錯段錯誤

產生段錯誤就是訪問了錯誤的記憶體段,一般是沒有許可權,或者根本就不存在對應的物理記憶體,尤其常見的是訪問0位址. 在程式設計中以下幾類做法容易導致段錯誤,基本是是錯誤地使用指標引起的

1)訪問系統資料區,尤其是往 系統保護的記憶體位址寫資料

最常見就是給乙個指標以0位址

2)記憶體越界(陣列越界,變數型別不一致等) 訪問到不屬於你的記憶體區域

解決方法

我們在用c/c++語言寫程式的時侯,記憶體管理的絕大部分工作都是需要我們來做的。實際上,記憶體管理是乙個比較繁瑣的工作,無論你多高明,經驗多豐富,難免會在此處犯些小錯誤,而通常這些錯誤又是那麼的淺顯而易於消除。但是手工「除蟲」(debug),往往是效率低下且讓人厭煩的,本文將就"段錯 誤"這個記憶體訪問越界的錯誤談談如何快速定位這些"段錯誤"的語句。

下面將就以下的乙個存在段錯誤的程式介紹幾種除錯方法:

以下是程式**

dummy_function(void)

2 7 int main(void)

8 作為乙個熟練的c/c++程式設計師,以上**的bug應該是很清楚的,因為它嘗試操作位址為0的記憶體區域,而這個記憶體區域通常是不可訪問的禁區,當然就會出錯了。我們嘗試編譯執行它:

1.利用gdb逐步查詢段錯誤

這種方法也是被大眾所熟知並廣泛採用的方法,首先我們需要乙個帶有除錯資訊的可執行程式,所以我們加上「-g -rdynamic"的引數進行編譯,然後用gdb除錯執行這個新編譯的程式,具體步驟如下:

哦?!好像不用一步步除錯我們就找到了出錯位置d.c檔案的第4行,其實就是如此的簡單。

從這裡我們還發現程序是由於收到了sigse**訊號而結束的。通過進一步的查閱文件(man 7 signal),我們知道sigse**預設handler的動作是列印」段錯誤"的出錯資訊,並產生core檔案,由此我們又產生了方法2

2.通過對core檔案進行除錯

哇,好歷害,還是一步就定位到了錯誤所在地,佩服一下linux/unix系統的此類設計。

接著考慮下去,以前用windows系統下的ie的時侯,有時開啟某些網頁,會出現「執行時錯誤」,這個時侯如果恰好你的機器上又裝有windows的編譯器的話,他會彈出來乙個對話方塊,問你是否進行除錯,如果你選擇是,編譯器將被開啟,並進入除錯狀態,開始除錯。

linux下如何做到這些呢?我的大腦飛速地旋轉著,有了,讓它在sigse**的handler中呼叫gdb,於是第三個方法又誕生了

3.段錯誤時啟用除錯程式

怎麼樣?是不是依舊很酷?

以 上方法都是在系統上有gdb的前提下進行的,如果沒有呢?其實glibc為我們提供了此類能夠dump棧內容的函式簇,詳見 /usr/include/execinfo.h(這些函式都沒有提供man page,難怪我們找不到),另外你也可以通過gnu的手冊進行學習

4.利用backtrace和objdump進行分析

1#include

2 #include

3 #include

4 #include

5 void dummy_function(void)

6 12 void dump(int signo)

13 {

1415   void*array[10];

16   size_t size;

17   char**strings;

18   size_t i;

1920   size=backtrace(array,10);

21   strings =backtrace_symbols(array,size);

2223   printf("obtained %zd stack frames.\n",size);

2425   for(i=0;i這次你可能有些失望,似乎沒能給出足夠的資訊來標示錯誤,不急,先看看能分析出來什麼吧,用objdump反匯程式設計序,找到位址0x804876f對應的**位置:

gdb 除錯段錯誤

開發嵌入式linux的時候經常會遇到segmentation fault,也就是段異常錯誤,一般是使用錯誤的指標訪問記憶體導致。這種錯誤可以通過開啟核心的異常資訊輸出,再用gdb對發生段異常的位址進行定位。1.開啟核心的異常資訊輸出 mips的核心 關閉了arch mips mm fault.c的d...

gdb 除錯段錯誤

利用執行時產生core檔案,再利用gdb除錯找出段錯誤在哪一行 ulimit c unlimited使用該bash命令,可以使執行時段錯誤產生core檔案。1.gcc g 編譯 gcc g o a a.c2.執行檔案,便會產生乙個core.檔案 a3.除錯core檔案 gdb a core.便可以直...

gdb除錯段錯誤

一 gdb的除錯命令。c語言是 cc g tst.c o tst c 是g g o 生成的檔案 file.cpp c 除錯程式命令 gdb file 啟動,羅列 行數ist 1,break 行數 info break,run r 除錯執行,step s 單步除錯,檢視變數 print p 變數名,檢...