Thread Crash feststellen
-
Hi @ all!
Gibt es eine API-Funktion, mit der man feststellen kann, ob ein Thread, aus welchem Grund auch immer, abgestürzt ist und ihn dann so beenden kann, damit nicht gleich das ganze Programm abstürzt? Also z.B.: ein Guard-Thread überprüft alle x Sekunden, ob ein Thread abgestürzt ist. Ist dies der Fall wird der Thread beendet und das Programm läuft weiter.
-
Nein, eine API-Funktion gibts dafür nicht... Was verstehst du denn unter "abgestürzt"? Endlosschleife oder wie?
Mfg,
Badestrand
-
Damit mein ich "abgestürzen", wie ein normales Programm abstürzt, z.B. bei einer Division durch 0. Nur wenn das bei einem einzelnen Thread passiert kommt zwar ne Fehlermeldung, dass das Programm angeblich beendet werden musste, der Haupt-Thread aber läuft ohne Probleme weiter. Erst wenn man die Fehlermeldung wegklickt, wird der komplette Prozess dem Erdboden gleich gemacht.
-
Du kannst es mit dem Debugger probieren, aber Thread zu debuggen ist in der Regel schwieriger...
-
Dr. C++ schrieb:
Damit mein ich "abgestürzen", wie ein normales Programm abstürzt, z.B. bei einer Division durch 0. Nur wenn das bei einem einzelnen Thread passiert kommt zwar ne Fehlermeldung, dass das Programm angeblich beendet werden musste, der Haupt-Thread aber läuft ohne Probleme weiter. Erst wenn man die Fehlermeldung wegklickt, wird der komplette Prozess dem Erdboden gleich gemacht.
Ist glaub ich auch ganz gut so. Wenn dein Thread jetzt aus speicherbereich liest, aus dem er garnicht lesen darf, dann könntest du das ja ausnutzen und irgendwas anzustellen, wenn dei Hauptthread damit weiter arbeiten kann.
-
Das andere Threads weiterlaufen während die "böses böses Programm" Fehlermeldung angezeigt wird ist IMHO ein riesen Bug!
Ich für meinen Teil möchte eigentlich nicht dass mein Programm noch weiterläuft wenn einer meiner Threads eine Access-Violation hingelegt hat.
-
Vielleicht suchst du sowas:
- http://msdn.microsoft.com/library/en-us/debug/base/structured_exception_handling.asp
-
Es gibt natürlich eine Funktion um festzustellen ob ein Thread "abstürzt". Dazu musst Du einen "Unhandled-Exception-Filter" setzen:
Siehe:
SetUnhandledExceptionFilter
-
hustbaer schrieb:
Das andere Threads weiterlaufen während die "böses böses Programm" Fehlermeldung angezeigt wird ist IMHO ein riesen Bug!
Ich für meinen Teil möchte eigentlich nicht dass mein Programm noch weiterläuft wenn einer meiner Threads eine Access-Violation hingelegt hat.Das ist genau mein Problem: das Programm muss weiterlaufen. Es ist eine Server-Anwendung und wenn da nur ein User Mist baut und über ein selbst geschriebenes Progg falsche Daten sendet kann der Thread crashen und damit wäre dann gleichzeitig der ganze Prozess im Eimer.
@Jochen Kalmbach: Genau so eine Funktion hab ich gesucht, thx
. Mich würde nur noch interessieren, wie man an das Handle bzw. die ID des Threads kommen kann.
-
Hallo Dr. C++,
wenn du einen "Unhandled-Exception-Filter" für dein Programm installierst und dieser aufgerufen wird, kannst du darin über GetCurrentThreadId und OpenThread ein Handle auf den Thread bekommen. Man befindet sich sozusagen in dem Thread der "abstürtzt".
Ich bin auch gerade dabei eine Library die ungehandelte Programm-/Threadabstürze abfängt zu programmieren. Und deine Idee z.B. den abgestürzten Thread zu beenden, das Programm aber weiterlaufen zu lassen hatte ich noch gar nicht, danke dafür. Werd ich wohl bei mir einbauen
Gruß
yogle
-
Jetzt nochmal ne Frage: kann man den Unhandled-Exception-Filter auch so einstellen, dass der nur die Threads abfängt, die von dem Thread gestartet wurden, der auch SetUnhandledExceptionFilter() aufruft?
Also: es laufen x "Haupt"-Threads, jeder dient als Server für je einen Port. Es stürzt ein Thread ab, der von Haupt-Thread x gestartet wurde. Haupt-Thread x hat zuvor den Unhandled-Exception-Filter auf GuardThreadX gesetzt. Jetzt sollen quasi jeder abgestürzte Thread, dem richtigen Haupt-Thread zugeordnet werden.
Geht das?
-
Nop, also nicht das ich wüsste.
SetUnhandledExceptionFilter setzt halt eine deinen eigenen Filter also Toplevel-Filter für das *gesamte* Programm.
Wenn du mehrmals SetUnhandledExceptionFilter aufraufst ersetzt du nur den obersten durch den neusten.Das Programm kannst du danach weiterführen, indem du EXCEPTION_CONTINUE_EXECUTION zurückgibst, allerdings musst du dann den EIP des Threads eine Instruktion weitersetzen, was nicht einfach ist, oder du beendest den Thread irgendwie. Da du dich aber selber darin befindest weiß ich (noch) nicht wie man so etwas machen könnte
-
@Dr. C++: Das was Du suchst, solltest Du via
__try __except()
in dem Thread realisieren.
-
Das mit der richtigen Zuordnung der Unhandled-Exception-Filters kann ich also vergessen. Aber gibts dann wenigstens noch die Möglichkeiten herauszufinden, mit welchem Parameter der Thread gestartet wurde(also DWORD WINAPI ThreadFunc(LPVOID lpParam); )?
-
Dr. C++ schrieb:
Das mit der richtigen Zuordnung der Unhandled-Exception-Filters kann ich also vergessen
Es gibt halt keine Unhandled-Exception-Filters sondern nur einen. Und mit
__try __except
lassen sich halt auch nicht alle Exceptions abfangen. Bei Access Violations, Divison durch 0 usw. haste da keine Chance.
Dr. C++ schrieb:
Aber gibts dann wenigstens noch die Möglichkeiten herauszufinden, mit welchem Parameter der Thread gestartet wurde(also DWORD WINAPI ThreadFunc(LPVOID lpParam); )?
Das sollte über einen StackWalk bis zum Startpunkt des Threads möglich sein. Dort kannst du dann den Parameter auslesen. Der StackWalk und das Auslesen des Parameters kannste aber nur sinnvoll machen, wenn bei deinem Programm Debug Symbole dabei sind (*.pdb Datei beim VC Compiler/Linker).
-
Wenn es nicht mal ne "normale" Möglichkeit gibt den Param vom Threadaufruf zu bekommen, werd ich wohl alle Threads in map registrieren müssen - verdammter Speicherfresser
.
-
yogle schrieb:
Und mit
__try __except
lassen sich halt auch nicht alle Exceptions abfangen. Bei Access Violations, Divison durch 0 usw. haste da keine Chance.
????
-
Jochen Kalmbach schrieb:
yogle schrieb:
Und mit
__try __except
lassen sich halt auch nicht alle Exceptions abfangen. Bei Access Violations, Divison durch 0 usw. haste da keine Chance.
????
LOL, äh weiß auch nicht was mich da geritten hat
Natürlich kannst du dadurch solche Exceptions abfangen...
-
@Jochen Kalmbach: genau das hab ich jetzt noch gesucht! Funzt einwandfrei, thx!