2009-08-14 12 views
4

Meine Win32-Konsolenanwendung verwendet eine Fremdanbieterbibliothek. Nach dem Beenden von WinMain beginnt die globale Zerstörung von Objekten und ein AV findet irgendwo tief im Inneren statt. Ich bin wirklich versucht, nurWas genau ist das Risiko bei der Verwendung von TerminateProcess?

irgendwo am Ende von WinMain zu schreiben. Wenn ich dies tue, endet die Anwendung anmutig.

Aber MSDN says dass so kann den Zustand der globalen Daten durch Dynamic Link Libraries (DLLs) verwaltet, die nicht klar ist. Ich verstehe, dass, wenn ich ein globales Objekt habe, sein Destruktor nicht ausgeführt wird und ich riskiere, keine Datenbankverbindung oder etwas Ähnliches zu finalisieren. Ich habe so etwas in meinem Programm nicht.

Was genau ist das Risiko bei der Verwendung von TerminateProcess? Wie kann ich feststellen, ob ich es für meinen Zweck verwenden kann?

+0

Was ist ein "AV"? –

+1

AV = Zugriffsverletzung, Absturz aufgrund eines schlechten Speicherzugriffs – Michael

+0

Welcher Art ist diese Drittanbieterbibliothek? –

Antwort

5

Im Allgemeinen werden die schlechten Dinge bei der Interaktion mit Objekten außerhalb Ihres Prozesses passieren. Ein Beispiel dafür ist, dass Sie über einen gemeinsam genutzten Speicher verfügen, der von mehreren Prozessen verwendet wird, in die Ihr Prozess schreibt und in die andere Prozesse lesen und/oder schreiben. Normalerweise wird zum Synchronisieren des Lesens und Schreibens ein Mutex verwendet. Wenn ein Thread in Ihrem Prozess den Mutex erworben hat und gerade Änderungen durchführt, wenn TerminatePorcess aufgerufen wird, wird der Mutex abgebrochen und der gemeinsam genutzte Speicher möglicherweise in einem inkonsistenten Zustand belassen.

Ich vermute, dass Sie eine der Bibliotheken von Drittanbietern vermissen. DllMain ist etwas einschränkend, so dass die Bibliothek Funktionen initialisieren und nicht initialisieren kann, die Sie aufrufen sollen.

+1

Ausgewählt für ein schönes Beispiel für einen Fall, der Probleme verursachen könnte. Nach dem Debuggen dieses Problems fand ich heraus, dass die Bibliothek nicht immer unsere Callback-Funktion aufruft, die vor dem Entladen eine korrekte Deinitialisierung durchführen würde. Ohne Deinitialisierung wurden statische globale Objekte in der Reihenfolge zerstört, die dazu führten, zuerst einen Heap mit einem Objektpool zu zerstören und dann zu versuchen, diese Objekte freizugeben. Dies führte zum Absturz, da die Objektzeiger bereits auf den freigegebenen Heap-Speicher verwiesen. – sharptooth

+0

Da es einen Punkt in unserem Code gab, der immer während der Beendigung der Anwendung aufgerufen wurde, habe ich gerade einen Schritt hinzugefügt, der dem entspricht, was dieser Rückruf getan hat. Und das Problem ist weg. – sharptooth

+0

Freut mich zu hören, dass Sie das Problem gelöst haben –

6

Basierend auf der Dokumentation für diese und ExtiProcess scheint es das primäre Anliegen ist, dass DLLs ohne einen Aufruf von DllMain mit dem Flag DLL_PROCESS_DETACH entladen werden.

Meine 2cents: Die Dokumentation wird paranoid, dass Sie einige kritische Operation verärgern, die in DllMain + DLL_PROCESS_DETACH ausgeführt wird. Jeder, der davon abhängig ist, um einen kritischen Zustand aufrechtzuerhalten, ist dem Task-Manager bereits ausgeliefert. Daher sehe ich kein großes Risiko bei der Verwendung dieser API.

+0

+1, aber ich würde es anders herum sagen: die Verwendung von TerminateProcess() ist genauso gefährlich wie das Töten von Prozessen über den Task-Manager. –

4

Es hängt davon ab, wie Sie "globale Daten" interpretieren. Wenn Sie meinen, dass es sich um Daten handelt, die im Adressraum des Prozesses gespeichert sind, macht der Hinweis keinen Sinn - wir wissen, dass die Erinnerung verschwindet, also wen interessiert es, was damit passiert?

Es kann sich also auf OS-weite Sachen beziehen, die eine DLL möglicherweise gemacht hat, die außerhalb der Lebensdauer eines Prozesses bestehen. Ein einfaches Beispiel wäre eine temporäre Datei, die möglicherweise bereinigt werden muss. stürze den Prozess zu oft ab und du hast keinen Speicherplatz mehr auf der Festplatte, also solltest du dich wahrscheinlich nicht daran gewöhnen.

6

AFAIK, wenn Sie nichts "Phantasie" tun (was beinhaltet, ist aber nicht beschränkt auf: Erstellen von Threads, Sperren, DB-Verbindungen, COM-Objekte), wird nichts Schreckliches passieren. Aber wie Earwicker says, Sie nicht wissen was OS-weite Sachen eine DLL tut, und Sie sicherlich nicht wissen, ob das in Zukunft ändern wird, so darauf verlassen, ist sehr fragil.

Sind Sie nicht neugierig, warum diese Zugriffsverletzung auftritt? Es könnte gut das Zeichen von etwas sein, das viel früher korrumpiert wurde. Bitte bestätigen Sie mindestens , dass der Fehler durch diese 3rd-Party-Bibliothek verursacht wird, z. indem Sie ein Programm schreiben, das mit der Bibliothek verbunden ist, aber dessen main() nichts tut und bestätigt, dass dies den gleichen Absturz verursacht.

+0

Gute Idee mit leeren Haupt() –