2009-03-05 7 views
3

Comment attraper et gérer efficacement les fautes de segmentation de C dans une application OSX Carbon?Bande d'exception pour l'application Carbon C dans OSX

Contexte: Je fais une application OSX Carbon. Je dois appeler une fonction de bibliothèque d'un tiers. En raison de problèmes de thread, la fonction peut parfois se bloquer, généralement parce qu'elle se met à jour depuis un thread, et qu'elle contient un pointeur ou un handle obsolète interne lorsque je l'interroge à partir d'un autre thread. La fonction est une boîte noire pour moi. Je veux être en mesure d'appeler la fonction, mais être capable de "attraper" si elle s'est écrasée et fournir un retour alternatif. Sous Windows, je peux utiliser les scripts __try {} et __except du simple Visual C et Intel C. J'essaye de faire le même genre de crash-catcher pour OSX. J'utilise du C pur sur une très grande application. J'appelle la fonction des millions de fois par seconde, donc l'efficacité est très importante aussi. (Impressionnante, les frais généraux __try() Windows est infiniment petit!)

Voici ce que j'ai expérimenté:

1) exceptions C++. Je ne suis pas sûr si les exceptions C++ capturent les accidents segfault. Et mon application est actuellement C. Je pourrais essayer les wrappers et #ifdefs pour le rendre C++ mais c'est beaucoup de travail pour l'application, et je ne pense pas que les exceptions C++ vont attraper le crash.

2) signal + setjump + longjmp. Je pensais que ça marcherait ... c'est pour ça que ça 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'est jamais appelé pendant le crash. Je peux tester manuellement (et réussir) en appelant relance (SEGV). Mais les accidents ne semblent pas vraiment l'appeler. Mes pensées sont que les applications CFM n'ont pas accès aux signaux BSD complets, seulement un sous-ensemble, et que les applications Mach sont nécessaires pour le Real Thing.

3) MPSetExceptionHandler. Pas bien documenté. J'ai tenté de définir un gestionnaire. Il a compilé et a couru, mais n'a pas attrapé le segfault.

Répondre

3

Etes-vous sûr de ne pas avoir un SIGBUS plutôt qu'un SIGSEGV?

Les prises ci-dessous SIGBUS comme causé 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 
+0

Oui. Je pense que la clé est d'attraper chaque exception de chaque type! – SPWorley