Question

Comment attraper et gérer efficacement les erreurs de segmentation de C dans une application OSX Carbon?

Contexte: je suis en train de créer une application OSX Carbon. Je dois appeler une fonction de bibliothèque depuis un tiers. En raison de problèmes de threads, la fonction peut parfois tomber en panne, généralement parce qu'elle se met à jour depuis un thread et qu'elle contient un pointeur ou un pointeur périmé en interne lorsque je l'interroge depuis un autre. La fonction est une boîte noire pour moi. Je veux pouvoir appeler la fonction mais pouvoir "attraper" s'il s'est écrasé et s'il fournit un retour alternatif. Sous Windows, je peux utiliser les __try {} et les __except des compilateurs Visual C et Intel C simples.

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

J'essaie de créer le même type de collecteur de collision pour OSX. J'utilise du C pur sur une très grande application. J'appelle la fonction des millions de fois par seconde, l'efficacité est donc également très importante. (Impressionnant, les frais généraux de Windows __try () sont extrêmement faibles!)

Voici ce que j'ai expérimenté:

1) Exceptions C ++. Je ne sais pas si les exceptions C ++ interceptent les plantages de segfault. Et mon application est actuellement en C. Je pourrais essayer les wrappers et #ifdefs pour le rendre C ++, mais cela représente beaucoup de travail pour l’application, et je ne pense pas que les exceptions C ++ rattraperont le blocage.

2) signal + setjump + longjmp. Je pensais que cela fonctionnerait ... c'est ce pour quoi il a été conçu. Mais j'ai configuré mon gestionnaire d'erreur SEGV [en fait, je l'ai configuré pour chaque signal!] Et il n'a jamais été appelé pendant le crash. Je peux tester manuellement (et réussir) lors de l'appel de la relance (SEGV). Mais les accidents ne semblent pas vraiment l'appeler. Mes pensées sont que les applications CFM n'ont PAS accès à la totalité des signaux BSD, mais seulement à un sous-ensemble, et que les applications Mach sont nécessaires à la réalité.

3) MPSetExceptionHandler. Pas bien documenté. J'ai essayé de définir un gestionnaire. Il a compilé et exécuté, mais n'a pas détecté l'erreur de segmentation.

Était-ce utile?

La solution

Êtes-vous sûr de ne pas obtenir un SIGBUS plutôt qu'un SIGSEGV?

Ce qui suit détecte SIGBUS en essayant d'écrire à l'emplacement de mémoire 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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top