OSX의 Carbon C 앱에 대한 예외 래퍼
-
03-07-2019 - |
문제
OSX Carbon Application에서 C에서 세분화 결함을 효율적으로 잡고 처리하려면 어떻게해야합니까?
배경 : OSX 카본 응용 프로그램을 만들고 있습니다. 제 3 자로부터 도서관 기능을 호출해야합니다. 스레딩 문제로 인해 기능은 때때로 한 스레드에서 업데이트되기 때문에 때때로 충돌 할 수 있으며 다른 스레드에서 쿼리 할 때 내부적으로 오래된 포인터 나 처리가 발생합니다. 기능은 나에게 블랙 박스입니다. 이 기능을 호출 할 수 있지만 충돌 한 경우 "캐치"할 수 있고 대체 반환을 제공 할 수 있습니다. Windows에서는 간단한 Visual C와 Intel C 컴파일러의 __try {} 및 __excrect를 사용할 수 있습니다.
/* Working Windows Example */
__try { x=DangerousFunction(y);}
__except(EXCEPTION_EXECUTE_HANDLER) {x=0.0;} /* whups, func crashed! */
나는 OSX에 대해 같은 종류의 충돌 사처를 만들려고 노력하고 있습니다. 매우 큰 응용 프로그램에서 Pure C를 사용하고 있습니다. 초당 수백만 번 기능을 호출하므로 효율성도 매우 중요합니다. (인상적으로, Windows __try () 오버 헤드는 헤아릴 수 없을 정도로 작습니다!)
내가 실험 한 내용은 다음과 같습니다.
1) C ++ 예외. C ++ 예외가 Segfault 충돌을 잡는 지 확실하지 않습니다. 그리고 내 앱은 현재 C입니다. 랩퍼와 #ifdef를 시도해 C ++를 만들 수는 있지만 이것은 앱의 많은 작업이므로 C ++ 예외가 충돌을 일으킬 것이라고 생각하지 않습니다.
2) 신호 + setJump + longjmp. 나는 이것이 효과가 있다고 생각했다 ... 그것은 그것이 설계된 것입니다. 그러나 SEGV 오류 핸들러를 설정했습니다. Rais (SEGV)를 호출 할 때 수동으로 테스트하고 성공할 수 있습니다. 그러나 충돌은 실제로 그것을 부르지 않는 것 같습니다. 내 생각은 CFM 애플리케이션이 전체 BSD 신호에 액세스 할 수없고, 하위 집합 만, Mach 응용 프로그램은 실제에 필요하다는 것입니다.
3) mpsetexception handler. 잘 문서화되지 않았습니다. 나는 핸들러를 설정하려고 시도했다. 컴파일하고 실행되었지만 Segfault를 잡지 못했습니다.
해결책
Sigsegv보다는 Sigbus를 얻지 못한다고 확신합니까?
아래는 메모리 위치에서 글을 쓰려고 시도한 SIGBUS를 포착합니다.
cristi:tmp diciu$ cat test.c
#include <signal.h>
static void sigac(int sig)
{
printf("sig action here, signal is %d\n", sig);
exit(1);
}
int main()
{
(void)signal(SIGSEGV, sigac);
(void)signal(SIGBUS, sigac);
printf("Raising\n");
strcpy(0, "aaksdjkajskd|");
}
cristi:tmp diciu$ ./a.out
Raising
sig action here, signal is 10