段錯誤?打的就是段錯誤!!

2021-10-23 07:24:54 字數 2207 閱讀 6458

呵,段錯誤?自從我看了這篇文章,我還會怕你個小小段錯誤?

請開啟你的linux終端,跟緊咯,準備發車!!嘟嘟嘟噠~~

#include

void

errfunc()

intmain()

這段**拿去執行,肯定段錯誤。

系統會在程式崩潰的那一剎那將整個核心的資訊記錄在乙個檔案裡邊。如果你是第一次,那麼ls是查不到的。

這樣:使用命令ulimit -a開啟ulimit這個檔案。會看到如下:

發現這個檔案大小預設為0,檔案根本就裝不進去,那麼就需要我們手動將這個檔案的大小改大一點:ulimit -c 10240,當然,可以設定別的大小,看你心情。

然後再執行一次段錯誤的檔案,然後去ls,就會發現乙個core.***x的檔案,這裡提醒一下,最好先ls,看看系統下有沒有已存在的core檔案,省的到時候不知道是哪個。

接下來有一步可走可不走的:可以使用命令file core.4377(我測試的號碼是這個) ,將core.4377這個檔案的具體資訊給顯示出來,命令最後會顯示這個core檔案是通過哪個檔案產生的。

最後一步:gdb除錯。這個執行檔案叫dcw,是我的。gdb dcw core.4377,就會看到如下:

在最後,它會告訴你,在那個函式、那個位址出了問題。有些比較高階的gdb甚至會告訴你是哪一行!!可惜我的gdb就不說。。。

最後退出gdb除錯:q,回車

段錯誤的原因無非是記憶體越界,據不完全統計,主要有以下這些情況:

1 使用非法的記憶體位址(指標),包括使用未經初始化及已經釋放的指標、不存在的位址、受系統保護的位址,唯讀的位址等,這一類也是最常見和最好解決的段錯誤問題,使用gdb print一下即可知道原因。

2 記憶體讀/寫越界。包括陣列訪問越界,或在使用一些寫記憶體的函式時,長度指定不正確或者這些函式本身不能指定長度,典型的函式有strcpy

(strncpy),sprintf

(snprint)等等。

3 對於c++物件,應該通過相應類的介面來去記憶體進行操作,禁止通過其返回的指針對記憶體進行寫操作,典型的如string類的c_str

()介面,如果你強制往其返回的指標進行寫操作肯定會段錯誤的,因為其返回的位址是唯讀的。

4 函式不要返回其中區域性物件的引用或位址,當函式返回時,函式棧彈出,區域性物件的位址將失效,改寫或讀這些位址都會造成未知的後果。

5 避免在棧中定義過大的陣列,否則可能導致程序的棧空間不足,此時也會出現段錯誤,同樣的,在建立程序/執行緒時如果不知道此執行緒/程序最大需要多少棧空間時最好不要在**中指定棧大小,應該使用系統預設的,這樣問題比較好查,ulimit一下即可知道。這類問題也是為什麼我的程式在其他平台跑得好好的,為什麼一移植到這個平台就段錯誤了。

6 作業系統的相關限制,如:程序可以分配的最大記憶體,程序可以開啟的最大檔案描述符個數等,在linux下這些需要通過ulimit、setrlimit、sysctl等來解除相關的限制,這類段錯誤問題在系統移植中也經常發現,以前我們移植linux的程式到vxworks下時經常遇到(vxworks要改核心配置來解決)。

7 多執行緒的程式,涉及到多個執行緒同時操作一塊記憶體時必須進行互斥,否則記憶體中的內容將不可預料。

8 在多執行緒環境下使用非執行緒安全的函式呼叫,例如 strerror 函式等。

9 在有訊號的環境中,使用不可重入函式呼叫,而這些函式內部會讀或寫某片記憶體區,當訊號中斷時,記憶體寫操作將被打斷,而下次進入時將無法避免地出錯。

10 跨程序傳遞某個位址,傳遞的都是經過對映的虛擬位址,對另外乙個程序是不通用的。

11 某些有特殊要求的系統呼叫,例如epool_wait,正常情況下使用close關閉乙個套接字後,epool會不再返回這個socket上的事件,但是如果你使用dup或dup2操作,將導致epool無法進行移除操作,此時再進行讀寫操作肯定是段錯誤的。

加油啦,一定是可以實現的啦!!

段錯誤總結

sigsegv是在訪問記憶體時發生的錯誤,它屬於記憶體管理的範疇 sigsegv是乙個使用者態的概念,是作業系統在使用者態程式錯誤訪問記憶體時所做出的處理。當使用者態程式訪問 訪問表示讀 寫或執行 不允許訪問的記憶體時,產生sigsegv。當使用者態程式以錯誤的方式訪問允許訪問的記憶體時,產生sig...

常見段錯誤

在linux記憶體管理中,linux結合了cpu架構採用了分段機制 分段就是將記憶體分成大小不同的段空間,將程序之間和程序內部不同資料段之間隔離起來 當程式記憶體的資料的訪問超出了系統所給這個程式資料段的範圍,系統就會給程序傳送乙個訊號sigsegv,程式將終止退出。所以,可以說段錯誤都是對記憶體操...

段錯誤除錯

1 gdb除錯 1 第一步是使用帶有除錯標誌 debugging flags 的方式編譯這段 如下 gcc g segfault.c 2 執行可執行程式 gdb a.out 進入gdb模式 gdb run 執行程式 starting program home dgawd cpsc 363 a.out...