Frage

Wie kann ich effizient fangen und Zugriffsfehler von C in einer OSX Carbon-Anwendung behandeln?

Hintergrund: Ich mache eine OSX Carbon-Anwendung. Ich muss eine Bibliotheksfunktion von einem Dritten nennen. Da Fragen der Threading kann die Funktion gelegentlich abstürzen, in der Regel, weil sie sich von einem Thread ist zu aktualisieren, und es ist etwas intern abgestanden Zeiger bekam oder behandeln, wie ich es von einem anderen abfragen. Die Funktion ist eine Blackbox für mich. Ich möchte in der Lage, die Funktion aufzurufen, aber in der Lage sein zu „fangen“, wenn es abgestürzt und liefern eine alternative Rückkehr. Unter Windows kann ich die einfache 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 bin mit reinem C auf eine sehr große Anwendung. Ich rufe die Funktion Millionen Mal pro Sekunde, so Effizienz ist auch 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 fangen. Und mein App ist derzeit C. I-Wrapper und #ifdefs versuchen könnte es ++ zu machen C, aber das ist eine Menge Arbeit für die App, und ich glaube nicht, C ++ Ausnahmen werden den Absturz fangen.

2) Signal + setjump + longjmp. Ich dachte, das würde funktionieren ... es ist, was es für entworfen ist. Aber ich meinen SEGV Fehlerhandler up [in der Tat ich es für jedes Signal eingerichtet!] Und es ist nie während des Absturzes genannt. Ich kann manuell testen (und erfolgreich), wenn erhöhen Aufruf (SEGV). Aber die Abstürze scheinen nicht wirklich zu nennen. Meine Gedanken sind, dass CFM-Anwendungen haben keinen Zugriff auf die vollständigen BSD-Signale, nur eine Teilmenge, und dass die Mach-Anwendungen notwendig sind, um für die reale Sache.

3) MPSetExceptionHandler. Nicht gut dokumentiert. Ich versuchte, einen Handler zu setzen. Es kompiliert und lief, aber nicht die segfault fangen.

War es hilfreich?

Lösung

Sind Sie sicher, dass Sie nicht ein SIGBUS eher dann ein SIGSEGV bekommen?

Die unten fängt SIGBUS als durch Versuch am Speicherplatz 0 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
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top