2014-10-20 16 views
5

Ich habe eine Mini-Core-Dump-Funktion (über __try/__ außer und MiniDumpWriteDump()) zum Windows-Build meiner Qt-Anwendung hinzugefügt, so dass, wenn meine Anwendung jemals abstürzt, eine .dmp-Datei geschrieben wird auf Platte für mich, um später zu schauen und zu debuggen.Was ist der beste Weg, um absichtlich meine Windows-Anwendung zum Absturz zu bringen?

Das funktioniert ziemlich gut, aber zum Testen hätte ich gerne eine bekannt-zuverlässige Methode, um mein Programm zum Absturz zu bringen. Es könnte zum Beispiel eine Schaltfläche "Jetzt abstürzen" in der GUI geben und wenn der Benutzer darauf klickt, wird die Anwendung absichtlich zum Absturz gebracht.

Eine Möglichkeit ist es natürlich zu tun, wie folgt aus:

int * badPointer = NULL; 
*badPointer = 666; 

Und das funktioniert für mich, aber ich weiß nicht, wie die Vorgehensweise, weil es auf undefiniertes Verhalten beruht - insbesondere die C++ - Standard erfordert erfordert den obigen Code, um einen Absturz zu verursachen, so ist es möglich (aus Sicht einer Sprachanwalts), dass einige zukünftige Version des Compilers nicht abstürzen wird, wenn der obige Code ausgeführt wird.

Als ein „offizieller“ -Ansatz, habe ich versucht, dies:

abort(); 

..., das das Programm nicht beenden, aber nicht den Windows-Structured Exception verursachen, die den MiniCrashDump Handler auslöst, so dass keine .dmp-Datei wird geschrieben.

Meine Frage ist, gibt es einen "Official Right Way", um mein Programm zu stürzen? Ich sehe, dass Windows-API eine RaiseException() -Funktion hat, die ich aufrufen konnte, aber ich bin mir nicht sicher, was die richtigen Argumente dazu sein sollten. Ist das der richtige Weg, oder gibt es einen gezielteren Anruf, den ich besser gebrauchen könnte?

+0

Hammer durch den Bildschirm. –

+1

Sie verwenden stark implementationsspezifische Schlüsselwörter und Verhalten und Sie machen sich Sorgen, was eine C++ - Spezifikation eines Tages dazu sagen könnte ?? Sicher, RaiseException() ist der offizielle Weg. –

+0

@HansPassant Es ist nicht die C++ - Spezifikation, die mich so sehr beunruhigt wie der MSVC-Optimierer, der gcc-artige Denkstricke wie "Ich weiß, dass badPointer NULL ist, und da Dereferenzierung eines NULL-Zeigers ein undefiniertes Verhalten ist, kann ich anfangen Optimiere das, schreibe "... und dann stürzt mein Crash-Button plötzlich nicht mehr ab. :) –

Antwort

3

Es ist vollkommen in Ordnung, einen Nullzeiger zu dereferenzieren, um eine Zugriffsverletzung zu verursachen, wenn Sie wissen, dass Sie unter Windows laufen - Windows bietet stärkere Garantien als die Sprache C++. C++ sagt, dass die Dereferenzierung eines Null-Zeigers Undefined Behavior ist, aber Windows definiert dies als eine Zugriffsverletzung (was in Bezug auf C++ völlig akzeptabel ist, da eine Zugriffsverletzung ein mögliches Ergebnis von nicht definiertem Verhalten ist).

Von Managing Virtual Memory:

Windows NT baut eine Sicherung in jedem Adressraum des Prozesses. Die oberen und unteren 65.536 Bytes jedes Prozesses sind permanent vom System reserviert. Diese Abschnitte des Adreßraums werden abzufangen Streuzeiger-Zeiger-Speicher reserviert, die im Bereich 00000000 -0000FFFF oder 7FFF0000 -7FFFFFFF zu adressieren versuchen. Es ist nicht zufällig, dass es leicht ist, Zeiger in diesem Bereich zu erkennen, indem einfach die unteren vier Nibbles (die beiden rechten Bytes) in diesen Adressen ignoriert werden. Im Wesentlichen ist ein Zeiger ungültig, wenn die oberen vier Nibbles 0000 oder 7FFF sind; Alle anderen Werte repräsentieren gültige Adressen.

Die erste Seite des Speichers wird immer als PAGE_NOACCESS abgebildet, so dass, wenn Sie versuchen, auf einen Null-Zeiger (oder einem Zeiger innerhalb von +/- 64 KB eines Null-Zeiger) zu lesen oder zu schreiben, werden Sie immer erhöhen eine Zugriffsverletzungsausnahme