2009-03-05 4 views
3

Wie kann ich Segmentierungsfehler von C in einer OSX Carbon-Anwendung effizient abfangen und verarbeiten?Ausnahme-Wrapper für die Carbon C-Anwendung in OSX

Hintergrund: Ich mache eine OSX Carbon-Anwendung. Ich muss eine Bibliotheksfunktion von einer dritten Partei aufrufen. Wegen Threading-Problemen kann die Funktion gelegentlich abstürzen, normalerweise weil sie sich selbst von einem Thread aktualisiert, und sie hat einen intern abgestandenen Zeiger oder Handle, während ich sie von einem anderen abfrage. Die Funktion ist für mich eine Black Box. Ich möchte in der Lage sein, die Funktion aufzurufen, bin aber in der Lage zu "fangen", wenn sie abgestürzt ist und eine alternative Rückgabe liefert. In Windows kann ich die einfachen Visual C und Intel C-Compiler __try {} und __except verwenden.

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

Ich versuche, die gleiche Art von Crash-Catcher für OSX zu machen. Ich verwende reines C auf einer sehr großen Anwendung. Ich rufe die Funktion millionenfach pro Sekunde auf, Effizienz ist also sehr wichtig. (Bestechend, das Windows-__try() Overhead ist unermesslich klein!)

Hier ist, was ich habe experimentiert mit:

1) C++ Ausnahmen. Ich bin nicht sicher, ob C++ - Ausnahmen die segfault-Abstürze abfangen. Und meine App ist derzeit C. Ich könnte versuchen, Wrapper und #ifdefs C++ zu machen, aber das ist eine Menge Arbeit für die App, und ich glaube nicht, C++ - Ausnahmen werden den Absturz zu fangen.

2) Signal + Setjump + Longjmp. Ich dachte, das würde funktionieren ... dafür wurde es entwickelt. Aber ich habe meinen SEGV Error Handler eingerichtet (ich habe ihn für jedes Signal eingerichtet!) Und er wird während des Absturzes nie aufgerufen. Ich kann beim Anheben (SEGV) manuell testen (und erfolgreich sein). Aber die Abstürze scheinen es nicht wirklich zu nennen. Meine Gedanken sind, dass CFM-Anwendungen KEIN Zugriff auf die vollständigen BSD-Signale haben, nur eine Teilmenge, und dass Mach-Anwendungen für das Real Thing notwendig sind.

3) MPSetExceptionHandler. Nicht gut dokumentiert. Ich habe versucht, einen Handler zu setzen. Es kompilierte und lief, aber nicht den segfault.

Antwort

3

Sind Sie sicher, dass Sie keinen SIGBUS, sondern einen SIGSEGV bekommen?

Die unten fängt SIGBUS wie verursacht durch den Versuch am Speicherplatz 0 zu schreiben:

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

Ja. Ich denke, der Schlüssel ist, JEDE Ausnahme jeder Art zu fangen! – SPWorley