一、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 變數名,檢...