Jeden Crash abfangen
-
Ist eine Access-Violation eine *Security-Exception*??????
Ich hab hier nur von /GS geredet; und das hat mit *Security* zu tun!Prinzipiell gilt hier die Regel: Wenn das Programm manipuliert wurde (beabsichtlicht oder unbeabsichtlich, z.B. durch Speicherüberschreiber), so ist dem Prozess nicht mehr zu trauen! Somit darf auch auf keinen Fall ein installierter Handler im selben Prozess aufgerufen werden.
-
Wenn bei Dir eine AV nicht abgefangen wird, so hat einfach eine anderer Software seinen eigenen Handler installiert und fängt diese ab...
Beachte auch, dass man sowas nicht (invasive) debuggen kann, da hier nie ein Unhandled-Exception-Handler aufgerufen wird. Das kann man nur "non-invasiv" debuggen....
-
Ich kapiers nicht...
#include <Windows.h> #include <iostream> using namespace std; LONG WINAPI SehHandler(PEXCEPTION_POINTERS pExceptionPtrs) { MessageBox(0, "SehHandler", 0, 0); return EXCEPTION_CONTINUE_SEARCH; } int main() { SetUnhandledExceptionFilter(SehHandler); // Crash 1 *(unsigned int*)(0) = 0; // Crash 2 unsigned char buf[] = { 1, 2, 3, 4 }; unsigned int param[10]; unsigned int ind = 0; for(unsigned int i = 0; i < 100000; ++i) { param[i] = *(unsigned int*)&buf[ind]; ind += 4; } for(int i = 0; i < 10000; ++i) cout << param[i] << endl; }
Nur Crash 1 (Crash 2 auskommentiert): SehHandler
Nur Crash 2 (Crash 1 auskommentiert): WER (0xc0000005)
Beide (nichts auskommentiert): WER (0xc0000005)Füge ich noch einen VectoredHandler hinzu, wird dieser bei allen drei Varianten aufgerufen.
-
Mit was für einem Exception-Model wird Dein Projekt übersetzt?
Beachte, dass per Default /EHsc aktiviert ist; Du solltest aber /EHa verwenden...
Und überschreibe mal nicht so viel... sonst kann es ja sein, dass Dein ganzes Programm ungültig wird...
-
/EHa war bereits gesetzt.
Jochen Kalmbach schrieb:
Und überschreibe mal nicht so viel... sonst kann es ja sein, dass Dein ganzes Programm ungültig wird...
Könnte sich aber um ein realistisches Szenario in einem fremden Programm handeln. Ich möchte halt, wie schon gesagt, auf jeden Crash reagieren können.
-
Wie Du gerade schon selber gesagt hast, ist dies nicht möglich.... wenn ich davon ausgehe, dass sehr viel Speicher überschrieben wird, dann kann auch mein Handler überschrieben sein... somit ist Dein Ansatz falsch.
Es gibt *keine* Möglichkeit _alle_ Exceptions abzufangen... nur eine hohe Wahrscheinlichkeit...Und was erwartest Du, wenn Du "EXCEPTION_CONTINUE_SEARCH" zurück gibst???? Dann kommt WER...
-
Bei mir funktioniert Dein Beispiel wunderbar... habe nur ein "printf" anstelle "MessageBox" gemacht.... je nachdem ob die DLL schon geladen ist, kann es kritisch sein ein DllMain in einem Exception-Handler zu verwenden....
Mit der MessageBoxA geht es bei mir aber auch...
-
Achso, das ist ja sch...
Noch ein Problem: Wenn ich den VectoredHandler im fremden Programm setze, wird er auch noch aufgerufen, nachdem ich schon längst wieder RemoveVectoredExceptionHandler erfolgreich aufgerufen habe.
Wie kann das sein?
-
Ich verstehe nicht genau was Du erreichen willst...
-
Ein fremdes Programm wird um eine DLL erweitert. Diese soll möglichst alle Crashes abfangen.
Das Problem ist, dass sowohl beim normalen Start als auch beim normalen Beenden des Programms ein paar Exceptions fliegen...
Ich warte also ein wenig, bevor ich AddVectoredExceptionHandler aufrufe.
Beim Schließen des Programms rufe ich dann RemoveVectoredExceptionHandler auf, damit mein VecHandler nicht mehr aufgerufen wird, wird er aber trotzdem, einige Sekunden nach dem Remove-Aufruf.
-
Jochen Kalmbach schrieb:
Bei mir funktioniert Dein Beispiel wunderbar...
Warum bei mir nicht
Auch nicht mit printf, es erscheint garnix, gleich WER. Habe nix spezielles installiert, keinen AV oder sonstigen Kram...
-
Und warum bitte machst Du das nicht mit WER?
-
Weil ich dann keine (sehr wichtigen crashrelevanten) Logs mehr schreiben kann.
Zu dem RemoveVectoredExceptionHandler funktioniert nicht: Sorry, mein Fehler. AddVectoredExceptionHandler wurde danach nochmal durch eine HookInit-Funktion aufgerufen (Init bei Beendigung des Programms, naja...).
-
Kann denn ein Prozess verlässlich (und möglichst sofort, also ohne polling) erkennen, ob bei einem anderen Prozess WER gestartet hat?
-
Jeden Crash abfangen
Wie waere es mit: keinen Crash verursachen. Mache ich seit Jahren, funktioniert gut.
-
Hi schrieb:
Ein fremdes Programm wird um eine DLL erweitert. Diese soll möglichst alle Crashes abfangen.
-
Wäre es nicht intelligenter den Hersteller des Games um die Rausgabe der Sourcecodes zu bitten damit du den Server fixen kannst? Solche Hilfsangebote nehmen die doch bestimmt mit Kusshand an und vielleicht stellen die dich sogar an, wenn die sehen das du ein fähiger Mann bist.
-
An application can use Application Recovery and Restart (ARR) to save data and state information before the application exits due to an unhandled exception or when the application stops responding. The application is also restarted, if requested.
-
Hmm, ARR gibts leider nicht für WinXP/Server2003, das soll aber auch unterstützt werden.
Außerdem müsste man WER manuell weggklicken, um zu loggen (so wie ich das verstanden habe). Währenddessen würde man den Server weiterhin in der globalen Serverliste sehen (weil kein "server close" an den master gesendet wird), und Spieler würden versuchen zu verbinden -> timeout. Nicht so schön.@reani
Ne, Take2 ist stur. Haben da schon von mehreren Seiten höflich angefragt. Außerdem lässt sich der Server nicht so leicht fixen, es gibt sehr viele "Schwachstellen". Wichtiger wäre es mir, bei jedem Crash sofort einen eigenen Log schreiben zu können (und dann gleich terminate/restart).