2016-02-12 55 views
2

比方說,我編譯使用gcc --stack,4194304如何處理堆棧空間分段錯誤?

下一頁我的程序我做這樣的事情char what_is_wrong_with_me[8000000];

這將導致分段錯誤,但奇怪的是我有一個工作segv_handler,在那裏,如果我做一些愚蠢像char *stupid=0; *stupid='x';它會打印一條錯誤信息。

我的問題是,我該如何處理堆棧空間段錯誤?

+2

這就是一個貼切的變量名! – Claudiu

+1

查看http://man7.org/linux/man-pages/man2/sigaltstack.2.html – PSkocik

回答

2

你可以處理這個,但你已經耗盡了你的主堆棧。您需要爲信號處理程序設置一個備用堆棧。您可以使用系統調用sigaltstack

做到這一點當sigaction安裝您的段錯誤處理程序,您還需要在選項SA_ONSTACK

1

因此,你的進程耗盡了它分配的堆棧空間(故意在你的情況下,但不管它是否有意)。一旦嘗試將下一個堆棧幀寫入未分配頁面,就會向該進程發送一個SIGSEGV信號。

然後嘗試調用已安裝的信號處理程序。現在,讓我們記住SIGSEGV就像其他任何信號一樣。而且,正如您所知,當信號處理程序在接收到信號時被調用時,當信號處理程序返回時該進程繼續執行。

換句話說,信號處理程序被調用,就好像它是一個函數調用一樣,當函數調用返回時,原始執行線程恢復運行。

當然,你知道需要爲函數調用發生什麼,對吧?一個新的調用幀被壓入堆棧,包含返回地址和其他一些東西。你知道,所以當函數調用返回時,原始執行線程會從其停止的地方繼續運行(如果出現信號,您還會得到整個寄存器轉儲以及剩餘的CPU狀態,但這是不相關的細節) 。

而現在,或許,你可以計算出,全部由自己,回答自己的問題,爲什麼你的信號處理程序沒有得到在這種情況下,當堆棧空間已經耗盡調用...