段錯誤調試(core )

參考鏈接-段錯誤的幾種調試方式

段錯誤概念

什麼是段錯誤

段錯誤具體體現運行程序之後:
在這裏插入圖片描述
常常遇到這種情況,What???,啥原因也不說,你至少告訴我錯哪了,我改還不行嘛!!!好像女人生氣的感覺,反正你錯了,至於錯在哪,你自己好好想想,然後從出生開始想,到底哪裏得罪眼前的女人(開發一個龐大的系統從main開始看)。

一句話解釋段錯誤:訪問了你不該訪問的內存(好像是廢話,=> 你做了不該做的事)


段錯誤產生原因

  1. 訪問不存在的地址,null 或者 超出給定程序的內存
int main()
{
    int* p = NULL;
    *p = 0;
    return 0;
}
  1. 訪問了禁止訪問的內存(32bit機上,虛擬地址,0-4k是受保護地址,3G-4G是內核空間)
int main()
{
    int* p = (int*)1024;
    *p = 0;
    return 0;
}
  1. 修改了只讀區域
int main()
{
     const char *ptr = "test";
     char* x = const_cast<char*>(ptr);
     *(x+1) = 'i';
     return 0;
}
  1. 棧溢出
int main()
{
	main();
	return 0;
}


注意:指針越界

1. 堆上(new, molloc開闢的),只要還在合法的範圍了是不會有任何錯誤。
2.  棧上(函數內,局部數組),會出現段錯誤



段錯誤的調試

使用core文件

段錯誤會出發SIGSEGV信號,SIGSEGV信號會產生錯誤信息生成core文件,默認情況下linux系統不會生成core文件的,可以通過ulimit -c 查看一下系統core文件的大小限制(默認爲0),通過ulimit -c 1024修改core文件的大小限制,這樣當程序core dump的時候可以產生core文件了,或者我們直接在執行程序之前ulimit -c unlimited指定core文件大小沒有限制。

  1. 執行ulimit -c unlimited取消core文件大小限制
  2. 編譯程序Debug模式
  3. 執行程序,生成core文件
  4. 使用gdb調試,gdb a.out core

注意在調試的過程中大部分都是進入庫函數,可以用up命令進行跳出,最後定位發生段錯誤的地方,一般gdb調試使用的常用命令:

  • f:(補充:frame相當於函數調用的棧的一層)打印當前層棧的信息,棧的層編號,當前的函數名,函數參數值,函數所在文件及行號,函數執行到的語句
  • up down :表示向棧的上面/下面移動n層,可以不打n,表示向上移動一層。
  • info f : 打印當前層棧詳細的信息,調用函數的地址,被調用函數的地址等
  • info local :打印出當前函數中所有局部變量及其值
  • info args: 打印出當前函數的參數名及其值
  • p <表達式>: 輸出表達式的值

詳細命令參考

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章