28 9月 2007

[Linux] 截取、忽略系統發出的segmentation fault signal

因為有個程式有需求,要暫時把segmentation fault的signal SIGSEGV這個訊號忽略掉,比較利於之後程式的debug。原本想說用single();這個function指定發生SIGSEGV時交給指定的handler function去處理,就可以忽略掉。結果…「代誌並不是憨人所想得呷呢簡單」,執行之後的結果,卻是系統不斷地發出SIGSEGV這個signal…停都停不下來,擋都擋不住...連ctrl+c都不行Orz...

原來在fault發生後,必須處理造成fault的原因,再返回程式執行,返回程式後,會重新執行faulting instruction。所以若是想忽略segmentation fault的話,就必須透過longjmp()跳過可能發生錯誤的code,然後再繼續執行。

 

#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/ipc.h>
#include <setjmp.h>

jmp_buf setjmp_buffer;

void segmentFault(){
std::err<<"get a segment Fault!"<<std::endl;
longjmp( setjmp_buffer, 1 );//用0的話, setjmp()就會收到0,那麼可能會無窮回圈
}

int main(){

//當發出SIGSEGV這個signal時,交給segmentFault這個function處理
signal( SIGSEGV,(sig_t)segmentFault );

if( setjmp( setjmp_buffer ) == 0 )
{
// do something
std::cout<<"longjmp!!n";
char *a= NULL;
std::cout<<"ok"<<std::endl;
a[0] = '1';//cause a Segmentation Fault
}
else
{
// do something
std::cout<<"after longjmp.n";
}
return 0;
}

 

沒有留言: