如何避免SIGSEGV

2021-06-26 02:50:08 字數 2111 閱讀 2121

如何避免sigsegv

良好的程式設計習慣永遠是最好的預防方法。良好的習慣包括:

盡量按照c標準寫程式。之所以說是盡量,是因為c標準有太多平台相關和無定義的行為,而其中一些實際上已經有既成事實的標準了。例如c標準中,乙個越界的指標導致的是無定義的行為,而在實際情況中,乙個越界而未解引用的指標是不會帶來災難後果的。借用cu的乙個例子,如下:

1 #include

2 #include

3    

4 int main ()

雖然迴圈結束後,p指向了陣列a前乙個元素,在c標準中這是乙個無定義的行為,但實際上程式卻是安全的,沒有必要為了不讓p成為乙個野指標而把程式改寫為:

1 #include

2 #include

3    

4 int main ()

11     printf ("%c\n", *p);

12 }

當然,或許世界上真有編譯器會對「越界但未解引用」的野指標進行處理,例如引發乙個sigsegv。筆者無法100%保證,所以大家在實踐中還是各自斟酌吧。

徹底的懂得你的程式。和其它程式設計師不同的是,c程式設計師需要對自己的程式完全了解,做到精確控制。尤其在記憶體的分配和釋放方面。在操作每乙個指標前,你都應該清楚它所指向記憶體的出處(棧、堆、全域性區),並清楚此記憶體的生存週期。只有明白的使用記憶體,才能最大限度的避免sigsegv的產生。

大量使用assert。筆者偏好在程式中使用大量的assert,凡是有認為不該出現的情況,筆者就會加入乙個assert做檢查。雖然assert無法直接避免sigsegv,但它卻能盡早的丟擲錯誤。離錯誤越近,就越容易root cause。很多時候出現sigsegv時,程式已經跑飛很遠了。

開啟-wall  –werror編譯選項。如果程式是自己寫的,0 warning應該始終是一項指標(0 warning不包括因為編譯器版本不同而引起的warning)。一種常見的sigsegv**於向函式傳入了錯誤的引數型別。例如:

1 #include

2 #include

3 #include

45 int main ()

這個例子中,本意是要向buf拷貝乙個字串,但由於有乙個和buf名稱很相近的buff變數,由於乙個筆誤(這個筆誤很可能就來自你編輯器的自動補全,例如vim的ctrl – p, ctrl – n),strcpy如願的引發了sigsegv。實際在編譯期間,編譯器就提示我們warning: passing argument 1 of `strcpy' makes pointer from integer without a cast,但我們忽略了。

這就進一步要求我們盡量使用編譯器的型別檢查功能,包括多用函式少用巨集(特別是完成複雜功能的巨集),函式引數多用帶型別的指標,少用void*指標等。此例就是我們在2.2節提到的不經意的行為。

少用奇技淫巧,多用標準方法。好的程式應該邏輯清楚,乾淨整潔,像一篇朗朗上口的文章,讓人一讀就懂。那種充滿晦澀語法、怪異招數的試驗作品,是不受歡迎的。很多人喜歡把效能問題做為使用不標準方法的藉口,實際上他們根本不知道對效能的影響如何,拿不出具體指標,全是想當然爾。筆者曾經在專案中,將乙個執行頻繁的異常處理函式用彙編重寫,使該函式的執行週期從2000多個機器週期下降到40多個。滿心歡喜的提交了乙個patch給該項目的maintainer,得到的答覆是:「張,你具體測試過你的patch能帶來多大的效能提公升嗎?如果沒有明顯的資料,我是不願意將優雅的c**替換成這晦澀的彙編的。」於是我做了乙個核心編譯來測試patch,耗時15分鐘,我的patch帶來的整體效能提公升大約為0.1%。所以,盡量寫清楚明白的**,不僅有利於避免sigsegv,也利於在出現sigsegv後進行除錯。

當你的乙個需求,標準的方法不能滿足時,只有兩種可能:1.從一開始的設計就錯了,才會導致錯誤的需求;2.你讀過的**太少,不知道業界解決該問題的標準方法是什麼。計算機已經發展了幾十年,如果你不是在做前沿研究,遇到一定得用非標準方法解決的問題的機會實在太小了。正如我們經常用gdb跟蹤發現sigsegv發生在c庫里,不要嚷嚷說c庫有bug,大部情況是一開始你傳入的引數就錯了。

小結無論如何我們應該感謝sigsegv,是它讓我們能在不重啟機器的情況下除錯程式。相比那些由於記憶體使用錯誤而不得不一次又一次重啟機器來debug的核心工程師,sigsegv讓我們的生活變得輕鬆。理解sigsegv同時,我們也更加理解程式。希望這篇文件對初學c語言的同志有些許幫助。

如何避免 如何避免鋼板彈簧受損

鋼板彈簧是卡車上的貴重部件之一,它一旦發生故障或損壞,會影響車輛的行駛和操縱,甚至發生意外事故,所以司機師傅們平時要養成良好的駕駛習慣,避免卡車鋼板彈簧受損。鋼板彈簧在卡車懸架系統中起著緩衝作用,還擔負傳遞所有各向的力和力矩,以及決定車輪運動的軌跡,起到導向的作用。相比於氣囊式懸架,鋼板彈簧因為其結...

如何避免 小紅書如何避免降權!

小紅書如何避免降權!如何避免降權,避開了雷區自然可以提公升權重。1 暱稱不能帶任何的營銷產品詞 2 發布的筆記要統一主題 做美妝的統一發布跟美妝相關的筆記,做旅行的就發布跟旅行相關的筆記,很多人做小紅書喜歡跟風,什麼熱門就發什麼,其實這是乙個大忌。同一主題風格才更有利於體現你的專業性,讓系統知道你的...

如何避免死鎖

如何避免死鎖 1 使用事務時,盡量縮短事務的邏輯處理過程,及早提交或回滾事務 2 設定死鎖超時引數為合理範圍,如 3分鐘 10分種 超過時間,自動放棄本次操作,避免程序懸掛 3 優化程式,檢查並避免死鎖現象出現 4 對所有的指令碼和sp都要仔細測試,在正是版本之前。5 所有的sp都要有錯誤處理 通過...