/ MT und / MD baut abstürzt, aber nur, wenn Debugger nicht angebracht ist: Wie zu debuggen? [Duplikat]

StackOverflow https://stackoverflow.com/questions/811951

Frage

    

Diese Frage bereits eine Antwort hier:

         

Ich habe eine kleine Single-Threaded-C ++ Anwendung kompiliert und verknüpft Visual Studio 2005 verwenden, die Boost (crc, program_options und tokenizer) verwendet, ein paar Brocken von STL und verschiedene andere System-Header.

(Es ist Hauptzweck ist in einer CSV zu lesen und erzeugt eine benutzerdefinierten binäre .dat und ein gekoppeltes .h Strukturen erklärt, dass „erklären“, um das Format der .dat).

Das Werkzeug abstürzt (Zugriffsverletzung auf NULL), wenn außerhalb des Debugger ausführen, nur in Release. Z.B. F5 drücken nicht das Werkzeug zum Absturz bringen, Ctrl-F5 tut. Wenn ich den Debugger anzubringen, erhalte ich diesen Stapel:

ntdll.dll!_RtlAllocateHeap@12()  + 0x26916 bytes    
csv2bin.exe!malloc(unsigned int size=0x00000014)  Line 163 + 0x63 bytes C
csv2bin.exe!operator new(unsigned int size=0x00000014)  Line 59 + 0x8 bytes C++
>csv2bin.exe!Record::addField(const char * string=0x0034aac8)  Line 62 + 0x7 bytes  C++
csv2bin.exe!main(int argc=0x00000007, char * * argv=0x00343998)  Line 253   C++
csv2bin.exe!__tmainCRTStartup()  Line 327 + 0x12 bytes  C

Die Linie ist es stürzt auf eine etwas harmlos aussehenden Zuordnung:

pField = new NumberField(this, static_cast<NumberFieldInfo*>(pFieldInfo));

... Ich glaube nicht, dass es den Konstruktor noch nicht erreicht hat, ist es nur das Zuweisen von Speicher vor dem Konstruktor springen. Es hat mich auch diesen Code Dutzende Male von der Zeit ausgeführt stürzt, in der Regel in einer konsistenten (aber ansonsten nicht verdächtig) Lage.

Das Problem verschwindet, wenn sie mit / MTd oder / MDd (Debug-Runtime) Kompilieren und kommt bei der Verwendung von / MT oder / MD.

Die NULL aus dem Stapel geladen, und ich kann es in Speicheransicht sehen. _RtlAllocateHeap @ 12 + 0x26916 Bytes scheint wie ein großen Offset, wie ein falscher Sprung gemacht worden ist.

Ich habe _HAS_ITERATOR_DEBUGGING in einem Debug-Build versucht, und das nicht gebracht hat, bis etwas verdächtig.

ein HeapValidate am Anfang und Ende der Aufzeichnung Dropping :: addField zeigt einen OK-Heap bis hin zu, wenn er abstürzt.

Dies war früher zu arbeiten - ich bin nicht ganz sicher, was zwischen jetzt geändert und das letzte Mal, dass wir das Tool zusammengestellt (wahrscheinlich vor Jahren, vielleicht unter einem älteren VS). Wir haben eine ältere Version von boost versucht (1,36 vs 1,38).

Vor dem Abwurf auf manuelle Untersuchung des Codes zurück oder Fütterung dies zu PC-Lint und Kämmen durch seinen Ausgang, irgendwelche Vorschläge, wie diese effektiv debuggen?

[Ich werde gerne die Frage mit mehr Informationen zu aktualisieren, wenn Sie Informationen in den Kommentaren anfordern.]

War es hilfreich?

Lösung

Ein wenig Know Unterschied mit Debugger zwischen Laufen angebracht ist oder nicht das O Debug Heap (siehe auch Warum kommt den Code läuft langsam, wenn ich Debugger angeschlossen ?). Sie können den Debug-Heap deaktivieren, indem Sie die Umgebungsvariable _NO_DEBUG_HEAP verwenden. Sie können in Visual Studio dieses entweder in Ihrer Computereigenschaft oder in den Projekteinstellungen angeben.

Wenn Sie den Debug-Heap ausschalten, sollten Sie den gleichen Absturz auch mit Debugger sehen angebracht.

Wie gesagt, bewusst sein Gedächtnis Verfälschungen schwer zu debuggen sein kann, wie oft die eigentliche Ursache der Korruption (wie ein Pufferüberlauf) kann sehr weit sein, von wo aus man die Symptome sehen (der Absturz).

Andere Tipps

Application Verifier war super nützlich diese einmal zur Lösung I _NO_DEBUG_HEAP = 1 in Umgebung hatte, hier die akzeptierte Antwort sehen: Die Suche nach dem Gedächtnis wurde zuletzt befreit?

Es ist wahrscheinlich auch erwähnenswert, Pageheap , die ich während Application Verifier Suche gefunden. Sieht aus wie es einige ähnliche Boden abdeckt.

(FYI, es war ein Ein-Zeichen-Puffer-Überlauf:

m_pEnumName = (char*)malloc(strlen(data) /* missing +1 here */);
strcpy(m_pEnumName, data);

... noch ein weiteres lächerlich gutes Argument nicht strcpy direkt verwenden.)

Crashing innen neu oder malloc in der Regel ist ein Hinweis, dass die (interne) Struktur der malloc Implementierung beschädigt wurde. Dies ist die meiste Zeit durch das Schreiben an einer früheren Zuordnung (Pufferüberlauf) erfolgen. Dann auf den nächsten Anruf zu neuen oder malloc den App-Abstürze wie die interne Struktur nun ungültige Daten enthält.

Überprüfen Sie, ob Sie alle vorherigen zugewiesenen Speicherplatz überschreiben kann.

Wenn Ihre Anwendung ist tragbar Sie können versuchen, es auf Linux zu bauen und führen Sie es unter Valgrind .

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top