段錯誤以及調試方式


dummy_function(void)
{
    unsigned char * ptr=0x00;
    *ptr=0x00;
}
int main()
{
    dummy_function();
    return 0;
}

作為一名熟練的c/c++程序員,以上代碼的bug應該是很清楚的,因為它嘗試操作地址為0的內存區域,而這個地址區域通常是不可訪問的禁區,當然會出錯了。

 

方法1 :利用gdb逐步查找段錯誤
這種方法也是被大眾所熟知並廣泛采用的方法,首先我們需要一個帶有調試
信息的可執行程序,所以我們加上"-g -rdynamic“的參數進行編譯,然后調用
gdb調試運行這個新編譯的程序。

這個版本的gdb沒有提示出錯誤,以前的那個版本提示除了錯誤。
不僅提示出第幾行有錯誤,而且還提示出了了是因為進程是由於收到了SIGSEGV信號而結束的。通過進一步的查閱資料文檔(man 7 signal),
我們知道SIGSEGV默認handler的動作是打印”段錯誤“的出錯信息,並產生core文件,由此我們又產生了方法二。




方法2:分析core文件
但是奇怪了我的系統上並沒有生成core文件,linux系統默認禁止生成core文件,我們用下面的命令測試了一下果真如此。
我們將core文件的大小限制為1000, 這個好像每次都要設置不然輸不出來,估計要修改那個文件,不管了,知道就行了。
經過我們上面的設置之后終於生成了core文件。

哇,好厲害,還是一步定位到了錯誤所在地,佩服linux系統的此類設計,

方法3:段錯誤時啟動調試(試過沒成功)

    1    #include<signal.h>
     2    #include<stdlib.h>
     3    void dump(int signo)
     4    {
     5        //此處省略。。。。
          system("gdb");
     6        
     7    }
     8    dummy_function(void)
     9    {
    10        unsigned char * ptr=0x00;
    11        *ptr=0x00;
    12        sleep(10);
    13     }
    14    int main()
    15    {
    16      signal(SIGSEGV,&dump);
    17      dummy_function();
    18      return 0;
    19    }
大概思路就是這樣的,然后進入調試界面后輸入”bt"

方法4:利用backtrace和objdump進行分析。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM