2016-12-20 1 views
2

Ich bin auf der Suche nach einer Möglichkeit, segfaults und andere Fehler irgendwo in einem Programm zu fangen (die mehrere Threads verwendet, von denen einige von externen Bibliotheken erstellt werden). Ich benutze Visual Studio 2013 mit dem Intel C++ - Compiler 2015.Windows: Handle segdefaults in allen Threads

Einige externe DLLs - in einigen Fällen habe ich dies sogar mit Windows-Treibern gesehen - kann Fehler enthalten, die außerhalb meiner Kontrolle sind, und meine Software läuft 24/7 - Ich muss irgendwo einen Absturz protokollieren und meine Software neu starten können.

Bisher habe ich festgestellt, dass Sie einen Signal-Handler setzen können, der SIGSEGV und andere Signale behandelt. Basierend auf dem, was ich gelesen habe, würde es unter Linux genau das tun, was ich brauche (handle dieses Signal für alle Threads), aber unter Windows musst du den Signalhandler für jeden Thread separat setzen. Da ich nicht derjenige bin, der alle Threads erstellt (wenn ich es wäre, könnte ich einfach __try/__ catch verwenden), ist das keine wirkliche Option. Darüber hinaus sehe ich, dass, wenn ich einen Signalhandler in einem Thread setze und dann einen SIGSEGV verursache, wird er nicht vom Handler behandelt, während der exakt gleiche Code im Hauptthread gut funktioniert - nicht sicher, was läuft dort (aber auch eine Lösung dafür würde nicht helfen, da ich nicht alle Threads erstelle, und das Durchlaufen aller vorhandenen Threads in meinem Prozess, um Handler zu setzen, klingt wie eine sehr schlechte Idee).

Also, gibt es eine Möglichkeit, dies zu tun? Hier zu googeln und zu suchen hat nicht geholfen - ich habe mehrere Leute mit ähnlichen Fragen gefunden, aber keine Antworten, die in meiner Situation brauchbar sind.

Hinweis: Was habe ich jetzt, die sich perfekt in den Hauptthread funktioniert aber nicht, wenn ich diesen gleichen Code-Block zu jedem Thread kopieren:

SignalHandlerPointer previousHandlerSEGV = signal(SIGSEGV, SignalHandler); 
int *a; 
a = NULL; 
*a = 0; 

Antwort

1

über alle unbehandelte Ausnahmen in eine benachrichtigt zu erhalten Prozess können Sie SetUnhandledExceptionFilter aufrufen. Die Funktionalität ist dokumentiert als:

Ausgabe SetUnhandledExceptionFilter ersetzt den vorhandenen Ausnahmefilter der höchsten Ebene für alle vorhandenen und alle zukünftigen Threads im aufrufenden Prozess.

Innerhalb Ausnahme filtert es wird empfohlen, um einen Anruf zu MiniDumpWriteDump (in einem externen Prozess) auszulösen, ein Mini-Dump für die Offline-Analyse zu erzeugen. Sie können die Menge der Informationen steuern, die in den Minidump geschrieben werden (z. B. Threads, Module, Aufruf-Stacks, Speicher). Am wichtigsten ist, dass Sie den Aufruf-Stack des Threads ablegen können, der die nicht abgefangene Ausnahme zum Zeitpunkt der Ausnahmeerhöhung ausgelöst hat.

Als Alternative glaube ich, einige/die meisten/alle davon können automatisch durch die Registrierung für application recovery and restart erfolgen.

+0

SetUnhandledExceptionFilter funktioniert nicht, da dies keine Ausnahme ist. Aber es sieht so aus, als ob Ihr Link zur Registrierung für die Wiederherstellung und den Neustart von Anwendungen einwandfrei funktioniert! Ich musste es ein wenig zwicken, um es kompatibel mit Windows XP zu halten (ich habe immer noch viele Leute, die meine Software auf XP benutzen ... Es ist eine 24/7 Sache, die keinen Internetzugang benötigt). Wie auch immer, mit LoadLibrary in einem, wenn ich es geschafft habe, es zum Laufen zu bringen! –

+0

@HansvanZutphen: Was Sie als "Seg-Fehler" betrachten, wird tatsächlich als eine [SEH-Ausnahme] (https://msdn.microsoft.com/en-us/library/windows/desktop/ms680657.aspx) in implementiert Windows. Das Festlegen des unbehandelten Ausnahmefilters macht ** genau **, was Sie im Sinn hatten. – IInspectable

+0

Hm ... es hat nicht funktioniert, als ich es versuchte. Auch versuchen/fangen nicht fangen, müssen Sie __try und __catch verwenden. Aber ich denke, es wäre, wenn ich das (nicht standardmäßige) Compiler-Flag "/ EHa (Ja mit SEH-Ausnahmen)" wählen würde. –

Verwandte Themen