erkennen Beendigung des Programms (C, Windows)
Ich habe ein Programm, das bestimmte Aufgaben ausführen, bevor er abgeschlossen ist. Das problem ist, dass manchmal das Programm stürzt mit einer Ausnahme (wie Datenbank nicht erreichbar, etc).
Nun, gibt es irgendeine Möglichkeit zu erkennen, eine abnormale Beendigung und ausführen von code, bevor es stirbt?
Dank.
code ist geschätzt.
- Verwenden Sie ein SIGSEGV-signal-handler. 😉
Du musst angemeldet sein, um einen Kommentar abzugeben.
1. Win32
Die Win32-API enthält eine Methode, um dies zu tun, über die SetUnhandledExceptionFilter - Funktion, wie folgt:
2. POSIX/Linux
Ich in der Regel tun dies über die signal() - Funktion und dann mit der SIGSEGV-signal entsprechend. Sie kann auch mit dem SIGTERM-signal und SIGINT, aber nicht mit SIGKILL (by design). Sie können strace() um einen backtrace zu sehen, was die Ursache des Signals.
Gibt es sysinternals-forum-threads über den Schutz gegen end-Prozess versucht, durch Einhaken NT Internals, aber was Sie wirklich wollen, ist entweder ein watchdog-oder peer-Prozess (sinnvoll) oder eine Methode, mit der das abfangen katastrophale Ereignisse (ziemlich heikel).
Edit: Es gibt Gründe, warum Sie machen dies schwierig, aber es ist möglich abzufangen oder zu blockieren, versucht zu töten, die Ihren Prozess. Ich weiß, du bist nur versuchen zu bereinigen, bevor Sie verlassen, aber sobald jemand löst einen Prozess, der nicht sofort getötet, jemand fragt nach einer Methode, ihn zu töten, sofort, und so weiter. Jedenfalls, auf diesen Weg beschreiten, siehe oben verlinkten thread und Suche einige keywords, die Sie finden, in der es für mehr. hook ODER filter NtTerminateProcess etc. Wir reden hier über den kernel-code, Geräte-Treiber, anti-virus, Sicherheit, malware, rootkit-Zeugs hier. Einige Bücher helfen, in diesem Bereich sind Windows NT/2000 Native API, Undocumented Windows 2000 Secrets: A Programmer ' s Cookbook, Rootkits: das Untergraben der Windows-Kernel, und, natürlich, Windows® Internals: Fünfte Edition. Das Zeug ist nicht allzu schwer zu coden, aber ziemlich empfindlich zu bekommen genau das richtige, und Sie können mit unerwarteten Nebenwirkungen.
Vielleicht Anwendung Recovery und Neustart-Funktionen von nutzen sein könnte? Unterstützt von Vista und Server 2008 und höher.
Zur Verwendung SetUnhandledExceptionFilter, MSDN Social-Diskussion berät, damit diese zuverlässig arbeiten, patchen, dass die Methode der in-memory ist der einzige Weg, um sicherzustellen, dass Ihre filter aufgerufen wird. Rät stattdessen wickeln Sie mit __try/__except. Unabhängig davon, gibt es einige Beispiel-code und Diskussion der Filterung Aufrufe SetUnhandledExceptionFilter in dem Artikel "SetUnhandledExceptionFilter" und VC8.
Finden Sie auch unter Windows SEH Revisited auf Der Awesome-Faktor für einige Beispiel-code von AddVectoredExceptionHandler.
Es hängt davon ab, was machst du mit deinen "Ausnahmen". Wenn Sie behandeln Sie richtig und verlassen Sie das Programm, das Sie registrieren, können Sie Funktion, die aufgerufen werden auf Ausgang, mit
atexit()
.Funktioniert es nicht im Falle eines echten Abbruch, wie segfault.
Weiß nicht, über Windows, aber auf POSIX-konformen Betriebssystem, das Sie installieren können, signal-handler catch unterschiedliche Signale und tun Sie etwas über es. Natürlich können Sie nicht fangen
SIGKILL
undSIGSTOP
.Signal-API ist Teil des ANSI-C seit C89 also wahrscheinlich Windows unterstützt. Sehen
signal()
syscall für details.Wenn es Windows-only ist, dann können Sie SEH ( SetUnhandledExceptionFilter ) oder VEH (AddVectoredExceptionHandler, aber es ist nur für XP/2003 und höher)
Sorry, kein windows-Programmierer. Aber vielleicht
Registriert eine Funktion, die aufgerufen werden, wenn das Programm beendet wird.
http://msdn.microsoft.com/en-us/library/aa298513%28VS.60%29.aspx
Erste, obwohl dies ist ziemlich offensichtlich: Man kann nie eine völlig robuste Lösung-kann jemand immer nur auf die power Kabel zu beenden Ihren Prozess. Sie müssen also einen Kompromiss, und Sie müssen sorgfältig legen Sie die details des Kompromisses.
Einer der mehr robuste Lösungen ist, indem Sie den jeweiligen code in ein wrapper-Programm. Das wrapper-Programm startet ein "richtiges" Programm, wartet auf seinen Prozess zu beenden, und dann -- es sei denn, Ihr "echtes" Programm, das speziell signalisiert, dass Sie abgeschlossen hat normalerweise -- führt den cleanup-code. Das ist ziemlich Häufig für Dinge wie die test-Gurtzeuge, wo das test-Programm ist wahrscheinlich zum Absturz zu bringen oder Abbrechen oder sonst sterben auf unerwartete Weise.
Dass noch gibt Ihnen die Schwierigkeit, das, was passiert, wenn jemand eine TerminateProcess auf Ihre wrapper-Funktion, wenn das ist etwas, was Sie sich sorgen machen müssen. Falls nötig können Sie umgehen, indem Sie Sie als Dienst in Windows und die Verwendung der Betriebssystem-Funktionen zu starten, falls er stirbt. (Dies ändert die Dinge ein wenig; jemand konnte immer noch nur den Dienst beenden.) An diesem Punkt sind Sie wahrscheinlich an einem Punkt, wo Sie brauchen, um zu signalisieren erfolgreichen Abschluss von etwas hartnäckig, wie das erstellen einer Datei.
Veröffentlichte ich einen Artikel bei ddj.com über "post-mortem debugging" vor einigen Jahren.
Es umfasst Quellen für windows-und unix/linux zu erkennen abnormalen Beendigung. Durch meine Erfahrung, obwohl, ein windows-handler installiert SetUnhandledExceptionFilter ist nicht immer genannt. In vielen Fällen ist es aufgerufen, aber ich erhalte schon ein paar log-Dateien von Kunden, die nicht enthalten einen Bericht aus der installierten Handler, wo also eine ZUGRIFFSVERLETZUNG, war die Ursache.
http://www.ddj.com/development-tools/185300443