1

Nur selten erhalte ich einen Bericht von einem Benutzer, dass die Anwendung selbst mit einem Meldungsfeld beendet hat:Was ist "Microsoft C++ von Visual-Laufzeitbibliothek: Laufzeitfehler!" und wie kann ich es erfassen?

 
Microsoft C++ Visual Runtime Library 

Runtime error! 

Program: XXXXX.exe 

This application has requested the Runtime to terminate it in an unusual way. 
Please contact the application's support team for more information. 

Leider wird die Anwendung beendet silenly die Nachricht nach zeigt. Wir haben eine Crash-Dump-Generierung für strukturierte Ausnahmen, aber da es hier keine Ausnahme gibt, wird kein Crash-Dump generiert.

Was kann verursacht diese Nachricht sein?

Gibt es eine Möglichkeit, die Anwendung so zu ändern, dass anstelle von (oder zusätzlich zu) der Nachricht ein Minidump generiert wird (oder eine andere benutzerdefinierte Behandlung von der Anwendung ausgeführt wird)?

+0

Sie benötigen einen Minidump, um dies zu debuggen. Bitten Sie Ihren Benutzer, einen zu erstellen, während der Dialog angezeigt wird. Task-Manager in Vista/Win7 kann es tun. –

+0

Ich würde die Anwendung bevorzugen, um automatisch einen Minidump zu generieren, genau wie wenn es abstürzt. – Suma

Antwort

4

Die Nachricht wird von abort() erzeugt, die entweder direkt aufgerufen werden kann oder durch schlecht entworfene Ausnahmen - siehe unerwartete() oder terminate(), wie in Disable Microsoft Visual C++ Runtime Error beschrieben. Ob die Meldung angezeigt wird oder nicht, kann _set_abort_behavior Anruf eingestellt werden. Unter XP und später sollte die Anwendung standardmäßig einen Minidump erstellen und an den Windows-Fehlerberichtsdienst senden. Wenn Sie einen benutzerdefinierten Handler (zum Beispiel benutzerdefinierte Crash-Dump) benötigen, die nur (Nicht-Standard) Möglichkeit scheint zu sein, eine eigene Implementierung für den Abbruch() Funktion zur Verfügung zu stellen.

Die Standardimplementierung von Abbruch in Microsoft C Runtime Library ist folgende:

  • zeigt das Meldungsfeld oder druckt die Meldung an die Konsole
  • Handler für SIGABRT wirft wenn es irgendeine Störung
  • wenn
  • ist Reporting erlaubt ist, dann
    • löscht alle Handler für nicht behandelte Ausnahmen mit SetUnhandledExceptionFilter (NULL)
    • führt UnhandledExceptionFilter mit einer künstlich vorbereiteten Ausnahmeinformationen
  • Anrufe _exit (3) das Verfahren ohne zusätzliche cleanup in Ihrer Quelle

Einschließlich folgenden Code zu beenden, macht die Anwendung standardmäßig strukturierte Ausnahmebehandlung durchzuführen, (einschließlich eventuell vorhandener Filter):

extern "C" void __cdecl abort (void) 
{ 
    volatile int a = 0; 
    a = 1/a; 
} 
+0

Das fasst zusammen, was ich bisher gelernt habe - danke an shartzooth für seine Links und Ratschläge. – Suma

+1

Ersetzen Sie effektiv die CRT-Implementierung von 'abort()' mit Ihrer? – sharptooth

+0

Ja, genau. Achtung: Dies ist nicht standardgemäß (wie in der Norm definiert, wenn Sie Systemkopfzeilen verwenden, können Sie keine eigenen Implementierungen von Funktionen bereitstellen, die in diesen Kopfzeilen definiert sind). Achten Sie also darauf, dass Sie verstehen, was Sie tun. – Suma

3

Die Anwendung hat am wahrscheinlichsten abort() aufgerufen, weil terminate() aufgerufen wurde, nachdem eine Ausnahme einen Destruktor während des Abwickelns des Stapels oder weil eine Ausnahme nicht aufgerufen wurde.

Siehe an answer zu this related question für weitere Einzelheiten. Grundsätzlich müssen Sie alle Exceptions auf der obersten Ebene abfangen und behandeln, Ausnahmen dürfen nicht Destruktoren entkommen. Starten Sie Ihr Programm unter Debugger und aktivieren Sie „Stoppen Sie, wenn Ausnahme ausgelöst“ zu finden, was genau falsch innen geht und beheben, dass.

+0

Die C++ - Ausnahme ist in der Anwendung nicht aktiviert. Ich verstehe, dass es abort() von irgendwo anders aufgerufen werden könnte. Gibt es einen anderen Grund?Gibt es eine Möglichkeit, die Verarbeitung zu überschreiben, etwas anderes zu tun, anstatt die Nachricht zu zeigen? – Suma

+0

@Suma: Sie können '_set_abort_behavior()' verwenden, um das angezeigte Meldungsfeld zu unterdrücken. Sie können 'set_terminate()' auch verwenden, um den 'terminate() 'Handler zu ersetzen. Und wie können C++ - Ausnahmen nicht aktiviert werden? – sharptooth

+0

Auch "Starten Sie Ihr Programm unter Debugger" ist in meinem Fall nicht hilfreich, da es mir nie passiert ist. Es kommt sehr selten vor, ich bekomme diesen Bericht vielleicht ein paar Mal in einem Jahr von irgendeinem Benutzer. – Suma

Verwandte Themen