Pergunta

Como posso eficiente capturar e falhas alça de segmentação de C em um aplicativo OSX carbono?

Antecedentes: Estou fazendo uma aplicação OSX carbono. Devo chamar uma função de biblioteca de um terceiro. Por causa de enfiar questões, a função pode ocasionalmente falhar, geralmente porque está atualizando-se de um thread, e ele tem alguns ponteiro internamente obsoleto ou punho como eu consultá-lo a partir de outra. A função é uma caixa preta para mim. Eu quero ser capaz de chamar a função, mas ser capaz de "pegar" se ele caiu e fornecer um retorno alternativa. No Windows, eu posso usar o simples C Visual e __try Intel C do compilador {} e __except.

/* Working Windows Example */
__try { x=DangerousFunction(y);}
__except(EXCEPTION_EXECUTE_HANDLER) {x=0.0;} /* whups, func crashed! */

Eu estou tentando fazer o mesmo tipo de crash-coletor para OSX. Eu estou usando C puro em um aplicativo muito grande. Eu chamo os milhões de função de vezes por segundo, assim que a eficiência é muito importante também. (Impressionantemente, o __try Windows () sobrecarga é incomensuravelmente pequeno!)

Aqui está o que eu tenho experimentado com:

1) exceções C ++. Eu não tenho certeza se exceções C ++ pegar as falhas segfault. E meu aplicativo está atualmente C. Eu poderia tentar invólucros e #ifdefs para torná-lo C ++, mas este é um monte de trabalho para o aplicativo, e eu não acho que exceções C ++ vai pegar o acidente.

sinal 2) + setjump + longjmp. Eu pensei que isso iria funcionar ... é o que ele é projetado para. Mas eu configurar meu manipulador de erro SEGV [na verdade eu configurá-lo para cada sinal!] E nunca é chamado durante o acidente. Eu posso manualmente teste (e sucesso) ao chamar raise (SEGV). Mas as falhas não parecem realmente chamá-lo. Meus pensamentos são que aplicações CFM não têm acesso aos sinais BSD completos, apenas um subconjunto, e que aplicações Mach são necessários para a coisa real.

3) MPSetExceptionHandler. Não é bem documentada. I tentou definir um manipulador. É compilado e correu, mas não pegar o segfault.

Foi útil?

Solução

Tem certeza de que não está recebendo um SIGBUS em vez de um SIGSEGV?

A seguir capturas SIGBUS como causado pela tentativa de gravação na posição de memória 0:

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
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top