2010-06-10 3 views
1

내 Linux 응용 프로그램에서 SIGSEGV를 처리해야합니다. 그 이유는 코어 - 덤프를 생성하기 전에 일부 정리 (3-partry lib)가 완료되어야하기 때문입니다. 게다가, 정리는 스레드를 호출하는 컨텍스트에서 수행해야하며, 신호 처리기에서는 수행 할 수 없습니다. 그래서 신호 처리기에서 호출 스레드에 컨트롤을 전달하고, 정리가 끝난 후 raise (SIGSEGV)를 사용하여 코어 덤프를 생성합니다.Linux에서 SIGSEGV를 처리 하시겠습니까?

실제 문제는 signal_handler가 post_sem이나 다른 것을 사용하더라도 상관없이 호출 스레드에 컨트롤을 전달할 수없는 것 같습니다. 이 케이스를 처리 할 생각이 있으십니까? SIGSEGV를 납치 할 가능성이 있으며, SIGSEGV 처리기에서 다른 스레드로 복귀하여 정리를 수행 할 수 있습니까?

신호 (SIGSEGV, signal_handler);

signal_handler() { ... post_sem(); ...}

호출 스레드() { wait_sem(); clean_up(); ... }

+0

설명하신 방법은 사실 가장 가까운 것입니다. 'sem_post' (POSIX 버전)는 표준에 의해 비동기 신호에 안전해야합니다. –

답변

2

그것의 불가능 믿을 수 실행 당신이 SIGSEGV가 발생 한 후 코드에. 때로는 빠져 나갈 수도 있지만 나중에 프로그램이 의도 한대로 작동하는 것을 믿을 수는 없습니다. 예를 들어 손상된 힙 때문에 SIGSEGV가있는 경우 제 3 자 lib가 메모리를 정리하면 문제가 발생합니다.

신뢰할 수있는 솔루션을 얻으려면 그 정리 코드를 실행해야하는지 아니면 상황을 처리 할 다른 방법이 있는지 생각해보십시오 (다음 시작시 부정한 종료 확인 ...).

1

저는 메모리 상태를 정리하는 것을 시도해서는 안되며 특히 디스크에 쓰는 것이 좋습니다. 성공할 경우 데이터가 손상 될 수 있습니다.

가능한 경우 일부 상태 정보를 기록하면 디버깅을 도울 수 있지만 가능한 한 의존해서는 안됩니다.

대신 프로그램은 상태 정보를 로깅 한 후 기본 처리기 (코어 덤프 등)로 돌아가거나 _exit을 호출하고 정리를하지 않고 종료해야합니다.

충돌 후 다시 시작하려면 정리 작업을 수행해야하는 경우 대신 다음 시작시 수행하십시오.

3

당신은 SIGSEGV (즉, 심각한 오류) 이후에 정리하고 싶습니다 ... 나는 약간 이상하다고 생각합니다. 왜냐하면 1) 응용 프로그램을 디버깅하는 경우 모든 것을 그대로 코어 파일에 저장해야합니다. 정확히 무슨 일이 있었는지 확인하고 2) 고객을위한 릴리스 응용 프로그램을 가지고 있다면 (말하자면) ... SIGSEGV가 아니어야합니다. :) (내 문제가 아니라 그냥 ..)

주제에

클린업을 시도하는 스레드를 제외한 모든 스레드에서 SIGSEGV를 차단하려고 할 수 있다고 생각합니다. 이것은 os가 특정 스레드에 신호를 전달하도록해야합니다. 내가 생각할 수있는 다른 해결책은 setjmp()/longjmp() (이 중 어떤 것도 테스트하지 않았 음)의 행을 따라하는 것입니다.

일단 프로그램에 SEGV가 있으면 깨지기 쉽습니다 (즉, 정리가 실패하고 다른 SEGV 등을 생성 할 수 있음). 따라서 코어가 손상되는 것을 고려해야합니다.

+0

도움이되지 않습니다. 'SIGSEGV'는 무효 액세스를 야기한 특정 스레드에 전달되며 전체 프로세스는 아닙니다. –

관련 문제