linux C++ 莫名奇異的段錯誤(segmentation fault),無法調用其他函數


    進來在linux下開發C++項目,遇到了非常奇怪的bug。

項目須要多線程實現,在寫好代碼后,每當執行到線程函數內部,當內部調用其他函數如printf、fopen等時就會提示段錯誤(segmentation fault)。編程非常久了,自覺不會出現非常低級的語法錯誤,經細致檢查許久確實也未發現不論什么問題。在給非常多厲害的朋友看過代碼后也未能幫助找到這個bug,后來經自己一番思索最終找到問題所在。

以下先給出線程函數的簡化框架:

void* thread_func(void* rank) {
    long my_rank = (long) rank;
    printf("thread %ld is working...\n", my_rank);
    //...
    char buffer[BUFF_SZ];
    //...
}

    這段代碼編譯一定通過,執行時在變量賦值處不會有問題。可是當執行到printf調用函數就會出段錯誤,這說明找不到函數地址,可是為什么會有這個問題呢?!

    原來。注意看下buffer數組定義那行,里面數組大小BUFF_SZ是自己定義的全局常量,這個常量由於業務需求被定的較大(50MB左右)。這就是問題症結所在!這樣的數組定義占用的是線程棧內存,可是linux線程所占棧內存上限一般為8MB。這樣buffer實際上刷滿了整個線程棧內存,才會導致執行時線程內找不到函數入口。因此在這里mark一記,假設以后有人再遇到類似問題。希望能考慮下這個點。

    總的來說,解決這個bug后會發現這是個非常easy的問題,可是實際中真的非常難發現(耗費3天時間了。

)。主要有兩點原因:1.曾經我們非常少會申請特別大的棧內存,所以盡管我們能理解棧內存限制的原理,可是非常少有實際犯錯經歷。2.數組大小被以常量表示(企業多會有這樣的要求避免magic number)。難以發現這個數過大。所以。當真正碰到這樣的問題的時候,假設沒有經歷真的可能會浪費很多時間。希望這篇日后能幫助碰到類似bug的朋友少走彎路。少花時間。

    最后:

    解決方式:利用new動態分配內存開辟堆內存空間,但最后要記得delete釋放掉。

    找到bug的方法:先將函數體所有凝視,然后按程序段解凝視執行,看看是加入了哪些程序段造成的問題。

   


免責聲明!

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



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