2012-01-12 2 views
9

내 프로그램에 신호 처리기가 등록되어 있습니다. 원하지 않는 신호 (SIGABRT)를 받으면 신호 처리기에서 'exit (-1)'을 호출하여 프로세스를 종료합니다. 그러나 거의 발생하지 않는 것으로 알려지면서 exit()를 호출하지만 프로세스를 종료하지 못합니다.exit() 프로세스를 종료하지 못합니까?

문제는 무작위로 생성되었으며 exit()를 실행하는 것이 좋습니다.

exit()가 프로세스를 종료하지 못할 수있는 이유나 경우가있을 수 있습니다.

감사합니다.

+1

버그에 대한 또 다른 원인을 'exit'와 같은 기능보다 찾는 것이 가장 좋습니다.거의 항상, 컴파일러 나 표준 라이브러리 등에 버그가 있다고 생각할 때, 오류를 일으키는 것은 당신 자신의 실수입니다. – Shahbaz

+3

@Shahbaz : Mandar는 구현에서 버그를 묻지 않거나 버그가 있음을 제안하지 않습니다. 문제는 'exit'이 항상 프로그램을 종료하도록 지정되었는지, 그리고 응답이 아니오 (특히 신호 처리기에서 호출 된 경우)가 아닌지 여부입니다. –

+0

SIGABRT의 핸들러를 exit()로 설정하지 않는 이유는 무엇입니까? 시그널 핸들러에서 무엇을 하든지, atexit() 호출로 처리하십시오. –

답변

13

신호 처리기에서 exit() (으)로 전화 하시겠습니까? man 7 signal 당신이 시그널 핸들러에서 호출 할 때 보장하는 모든 기능이 작동을 볼 수 섹션 비동기 신호 안전 기능에서

: 신호 처리기 기능은 매우 조심해야

이후 다른 곳에서의 처리는 프로그램 실행 중 임의의 지점 인 에서 인터럽트 될 수 있습니다. POSIX는 "안전 기능"이라는 개념을 가지고 있습니다. 신호가 안전하지 않은 함수의 실행을 인터럽트하고 핸들러가 안전하지 않은 함수를 호출하면 프로그램의 동작이 정의되지 않습니다. 당신이 할 수있다

: (또한 POSIX.1-2001 기술 정오표 2라고도 함)

POSIX.1-2004는 다음과 같은 기능이 안전하게 시그널 핸들러 내에서 호출 할 수 있다는 보장에 대한 구현을 필요로 기능 _Exit(), _exit()abort()을 참조하십시오. 특히 exit()은 아닙니다. 따라서 시그널 핸들러에서 호출해서는 안됩니다.

신호 처리기 (printf() any?)에서 안전하지 않은 함수를 호출하더라도 대부분의 시간이 작동하지만 ... 항상 그런 것은 아닙니다.

+1

신호 처리기에서 비동기 신호 안전하지 않은 함수를 호출하는 것은 신호가 다른 비동기 신호가 안전하지 않은 함수를 인터럽트하지 않는 한 완벽하게 유효합니다 *. 이것은 "대부분의 시간 동안"작동하는 이유를 설명하지만 시그널 핸들러가 안전하지 않은 작업을 방해 할 수 없도록주의를 기울이면 올바른 코드로도 비동기 시그널이 안전하지 않은 함수를 시그널 핸들러에서 사용할 수 있음을 의미합니다 함수 (예를 들어, 대부분의 경우 마스크 된 신호를 남기고 파일 설명자 IO 및'select'와 같은 순수 산술 또는 비동기 신호 안전 라이브러리 호출을 수행하는 동안에 만 신호를 차단 해제합니다). –

+0

@R .. 당신 말이 맞아요. 그러나 실제로 특별한 경우를 제외하고는이를 보장하기가 어렵습니다. 개인적으로 안전하지 않은 기능을 함께 피하는 것이 훨씬 편리합니다. – rodrigo

+1

다음을 참조하십시오 : http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html –

3

예, 다음과 같은 몇 가지 상황이 있습니다 :

가 출구()가 처음들은 등록의 역순으로 atexit (에 의해 등록 된 모든 기능을), 부르겠다 기능 함수가

라는 것을 제외하고는 이전에 등록 된 기능이 등록 된 시점에 이미 호출 된 후. 각 함수는 등록 된 횟수만큼 호출됩니다. 이러한 함수를 호출하는 동안 longjmp() 함수를 호출하여 등록 된 함수에 대한 호출을 종료하면 동작은 정의되지 않습니다.

atexit() 호출로 등록 된 함수가 반환되지 않으면 나머지 등록 된 함수는 호출되지 않으며 나머지 exit() 처리는 완료되지 않습니다. exit()가 두 번 이상 호출되면 비헤이비어가 정의되지 않습니다.

exit의 POSIX 페이지를 참조하십시오.

자세한 내용은 상황에 도달했을 때 디버거를 연결하고 호출 스택을 살펴보십시오.

관련 문제