2014-02-26 2 views
5

나는 C에서 링크드리스트가 포함 된 프로젝트를 진행하고 있으며, 코드가 작동하지 않는다는 것을 증명하기 위해 코드 조각을 segfault해야한다. 하지만 내 코드는 충돌 할 수 없습니다.segfault를 처리하고 이동하는 방법은 무엇입니까?

typedef void sigfunc(int); 
sigfunc *signal(int, sigfunc*); 
void Handler(int sig) 
{ 
    if (sig == SIGSEGV) 
    printf("received SegFault\n"); 
    signal(SIGSEGV, &Handler); 
} 

그것은 segfault의 생존해야합니다 :

여기에 지금까지 내 처리기입니다. 지금까지 내가 얻은 것은 "recieved SegFault"의 무한 루프입니다. 미리 감사드립니다!

+1

신호 처리기에서'printf()'를 호출하는 것은 안전하지 않습니다. http://stackoverflow.com/questions/8493095/what-constitutes-asynchronous-safeness –

+1

특정 사용 사례의 경우, 유효성을 확인하기 위해 각 포인터를 확인하는 것이 좋습니다 (잘못된 포인터가 모두 null임을 보장해야 할 수도 있음). segfault가 발생하기 전에 감지합니다. – Brilliand

+5

이 질문은 downvotes를 축적하는 것 같다 ... 나는 그것이 특히 나쁜 질문에 동의하지 않는다; 유일한 중요한 문제는 정답이 "할 수 없다"는 것입니다 (그리고 질문자는 미리 알 수 없을 것입니다). – Brilliand

답변

7

일반적으로 SEGFAULT를 치면 프로세스가 완료됩니다.

전문 용어로는 복구가 가능할 수도 있지만 반복적 인 실패, 메모리 누수, 잘못된 포인터 및 기타 문제의 악몽을위한 처방입니다.

위의 모든 것을 피하기 위해 프로세스를 다시 시작할 수 없다면 setjmp()longjmp()을 사용하여 복구를 시도 할 수 있습니다. 예를 들면 :

가 목록에 한 다른 문제뿐만 아니라
#include <setjmp.h> 
jmp_buf restore_point; 
void Handler(int sig) 
{ 
    if (sig == SIGSEGV) 
    { 
     printf("received SegFault\n"); 
     signal(SIGSEGV, &Handler); 
     longjmp(restore_point, SIGSEGV); 
    } 
} 


void test() 
{ 
    int fault_code = setjmp(restore_point); 
    if (fault_code == 0) 
    { 
     // do something that might cause a segfault 
    } 
    else 
    { 
     printf("recovered from a fault; code = %d\n", fault_code); 
    } 
} 

또 다른는 .... 당신이 setjmp()를 호출하는 범위가 종료 될 때까지에만 유효 설정 점 (점프 버퍼)을 수행해야 복원한다는 것입니다 아니요 종료 된 범위로 다시 이동하십시오!

본질적으로 은 광범위하게는 goto이지만 점프 버퍼가 초기화 된 시점으로 돌아 가기 때문에 gobackto과 비슷합니다. 그것은 setjmp() 함수에 의해 setjmp()이 선형 적으로 호출 될 때 0을 반환하는 방식으로 초기화되는 방식으로 초기화되며, longjmp가되면 도달 할 때 0이 아닌 값을 반환합니다. 이 경우 longjmp() 초의 매개 변수가 무엇이든 반환합니다 (해당 매개 변수가 == 0이 아닌 경우에는 0이 아닌 값을 반환 함).

진지하게, 나는 당신에게 위험을 줄 수있는 충분한 정보를 제공해 왔지만주의 사항을 가볍게 여기지 마십시오. 당신이 문제를 해결하는 것보다이 방법으로 문제를 복합화하는 것이 훨씬 쉽습니다. 이 도구를 사용하는 데는 많은주의를 기울였습니다.

+1

나는 이것이 일반적으로 말하기는 끔찍한 생각이라는 것을 알고있다. 그것은 한 반의 프로젝트를위한 것입니다. 나는 결코 현실 세계에서이 쓰레기를 뽑아 내려고하지 않겠다. 나는 그 프로그램에 대한 모든 올바른 것들을 되돌리기 위해 그것을 segfault하고 생존해야합니다. 감사! – user3357612