Frage

Ich bin Debuggen eine (native) Multi-Threaded C ++ Anwendung unter Visual Studio 2008. Auf scheinbar zufällige Gelegenheiten, erhalte ich eine „Windows einen Haltepunkt ausgelöst hat ...“ Fehler mit dem Hinweis, dass dies aufgrund einem sein könnte Korruption in der Halde. Diese Fehler werden nicht immer die Anwendung abstürzen sofort, obwohl es wahrscheinlich ist, kurz nach dem Absturz.

Das große Problem mit diesen Fehlern ist, dass sie erst nach der Korruption Pop-up tatsächlich stattgefunden hat, die sie sehr schwer zu verfolgen und zu debuggen macht, vor allem auf einer Multi-Threaded-Anwendung.

  • Welche Art von Dingen, können diese Fehler verursachen?

  • Wie kann ich debuggen sie?

Tipps, Tools, Methoden, enlightments ... sind willkommen.

War es hilfreich?

Lösung

Application Verifier kombiniert mit Debugging tools für Windows eine erstaunliche Einrichtung ist. Sie können sowohl als Teil des bekommen Windows Driver Kit oder das leichtere Windows SDK . (Gefunden über Application Verifier, wenn eine früher Frage zu einem Heapbeschädigung Problem .) ich habe Bounds verwendet und Versichern ++ (in anderen Antworten) in der Vergangenheit auch erwähnt, obwohl ich, wie viel Funktionalität in Application Verifier war überrascht war.

Electric Fence (auch bekannt als "efence"), dmalloc , Schreiben Fest-Code :

  • Wachposten Werte : ein wenig mehr Platz vor und nach jedem alloc erlauben, maximale Ausrichtungsanforderung zu respektieren; füllt mit magischen Zahlen (hilft überläuft Fangpuffer und Unterschreitungen und die gelegentlichen „wild“ Zeigern)
  • alloc fill : neue Zuordnungen mit einem magischen Nicht-0-Wert füllen - Visual C ++ dies bereits für Sie tun in Debug baut (hilft Fang Verwendung von nicht initialisierten VARs)
  • freie Füllung : mit einem magischen Nicht-0-Wert in freigegebenen Speicher füllen, entworfen, um eine segfault auszulösen, wenn es in den meisten Fällen dereferenziert ist (hilft Zeiger fangen baumelt)
  • verzögert frei : nicht freigegebenen Speicher auf den Heap für eine Weile zurückkehren, halten Sie es gefüllt frei, aber nicht verfügbar (hilft Fang mehr baumelnden Zeigern, fängt der Nähe Doppel frees)
  • Tracking : die Lage zu erfassen, wo eine Zuordnung manchmal gemacht wurde nützlich sein kann

Beachten Sie, dass in unserem lokalen Homebrew-System (für ein eingebettetes Ziel) können wir die Verfolgung getrennt halten von den meisten anderen Sachen, weil der Laufzeitaufwand ist viel höher.


Wenn Sie in mehr Gründe interessiert sind, diese Zuordnung Funktionen / Betreiber zu überlasten, werfen Sie einen Blick auf meine Antwort auf „irgendeinem Grund Überlastung globalen Operator neu und löschen "?; schamlose Eigenwerbung beiseite, es andere Techniken aufgeführt, die, wie auch andere anwendbare Werkzeuge in Tracking Heapbeschädigung Fehlern hilfreich sind.


Weil ich hier meine eigene Antwort halten zu finden, wenn für alloc / Frei / Zaun Suche Werte MS verwendet, hier ist eine andere Antwort, die deckt Microsoft dbgheap füllen Werte .

Andere Tipps

Sie können durch Aktivieren Seitenheap für Ihre Anwendung viel Heapbeschädigung Probleme erkennen. Um dies zu tun Sie verwenden gflags.exe müssen, die als Teil von Debugging tools für Windows

Ausführen Gflags.exe und in der Bilddatei Optionen für die ausführbare Datei, „Aktivieren Seite Heap“ aus.

Jetzt ist Ihre exe starten und an einen Debugger anhängen. Mit Seitenheap aktiviert ist, bricht die Anwendung in Debugger sobald eine Heap-Beschädigung auftritt.

wirklich langsam Dinge nach unten und eine Menge von Laufzeitüberprüfung durchführt, versuchen Sie Folgendes an der Spitze Ihres main() oder gleichwertig in Microsoft Visual Studio C ++ Hinzufügen

_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF | _CRTDBG_CHECK_ALWAYS_DF );
  

Welche Art von Dingen, können diese Fehler verursachen?

Wenn man unerlaubte mit Speicher, beispielsweise nach dem Ende eines Puffers zu schreiben, oder in einen Puffer zu schreiben, nachdem es wieder auf den Heap befreit worden ist.

  

Wie kann ich sie debuggen?

ein Instrument verwenden, die Grenzen Prüfung auf die ausführbare Datei automatisiert ergänzt: d. H valgrind auf Unix oder einem Tool wie Bounds (Wikipedia schlägt auch Entschlacken und Versichern ++) unter Windows

Beachten Sie, dass diese Anwendung verlangsamen, so dass sie unbrauchbar sein, wenn Sie eine Soft-Echtzeitanwendung ist.

Eine weitere mögliche Fehlersuche Hilfe / Werkzeug könnte MicroQuill des HeapAgent sein.

Ein kurzer Tipp, dass ich von Erkennung Zugriff auf freigegebenen Speicher ist dies:

  

Wenn Sie den Fehler lokalisieren wollen   schnell, ohne zu überprüfen, jedes   Anweisung, die die Speicherzugriffe   Block, können Sie den Speicherzeiger eingestellt   auf einen ungültigen Wert, nachdem die Befreiung   Block:

#ifdef _DEBUG // detect the access to freed memory
#undef free
#define free(p) _free_dbg(p, _NORMAL_BLOCK); *(int*)&p = 0x666;
#endif

Das beste Werkzeug, das ich gefunden nützlich und arbeitete jedes Mal, ist Code-Review (mit gutem Code Gutachtern).

Anders als Code-Review, würde ich zuerst versuchen, Seite Heap . Seite Heap dauert einige Sekunden einzurichten und mit etwas Glück könnte es Ihr Problem lokalisieren.

Wenn kein Glück mit Seitenheap, download Debugtools für Windows von Microsoft und lernen, die WinDbg zu verwenden. Leider konnten Sie speziellere Hilfe nicht geben, aber debuging Multi-Threaded Heapbeschädigung ist mehr eine Kunst als eine Wissenschaft. Google für „WinDbg Heapbeschädigung“ und Sie sollten viele Artikel zu diesem Thema finden.

Sie können auch prüfen wollen, um zu sehen, ob Sie eine Verknüpfung gegen die dynamische oder statische C-Laufzeitbibliothek. Wenn Ihre DLL-Dateien verknüpfen gegen die statische C-Laufzeitbibliothek, dann haben die DLL-Dateien separate Haufen.

Wenn Sie also ein Objekt in einem DLL erstellen sind und versuchen, es in einem anderen DLL zu befreien, würden Sie die gleiche Nachricht erhalten Sie oben sehen. Dieses Problem wird in einer anderen Stack-Überlauf Frage verwiesen, Befreit Speicher in einem zugewiesenen verschiedene DLL .

Welche Art von Zuordnungsfunktionen verwenden Sie? Ich traf vor kurzem einen ähnlichen Fehler, die Heap * style Zuordnungsfunktionen verwenden.

Es stellte sich heraus, dass ich irrtümlich den Haufen mit der HEAP_NO_SERIALIZE Option zu schaffen. Dies macht im Wesentlichen der Heap-Funktionen ohne Thread-Sicherheit ausgeführt werden. Es ist eine Performance-Verbesserung, wenn sie richtig verwendet, aber nicht immer verwendet werden soll, wenn Sie HeapAlloc in einem Multi-Threaded-Programm werden [1]. Ich erwähne dies nur, weil Ihr Beitrag erwähnt Sie einen Multi-Threaded-App hat. Wenn Sie HEAP_NO_SERIALIZE überall verwenden, löschen Sie das und es wird wahrscheinlich Ihr Problem beheben.

[1] Es gibt bestimmte Situationen, in denen dies legal ist, aber es erfordert, dass Sie Anrufe Heap serialisiert * und ist in der Regel nicht der Fall für Programme mit mehreren Threads.

Wenn diese Fehler zufällig auftreten, besteht eine hohe Wahrscheinlichkeit, dass Sie Daten-Rennen anzutreffen. Bitte überprüfen Sie: Ändern Sie Shared-Memory-Zeiger von verschiedenen Threads? Intel Thread Checker kann helfen, solche Probleme in multithreaded Programm zu erkennen.

Zusätzlich für Werkzeuge zu suchen, sollten Sie für einen wahrscheinlichen Täter suchen. Gibt es eine Komponente, die Sie verwenden, vielleicht nicht von Ihnen geschrieben, die so angelegt sind nicht und getestet in einer Multithread-Umgebung laufen zu lassen? Oder einfach eine, die Sie nicht wissen hat in einer solchen Umgebung ausgeführt werden.

Das letzte Mal, es mir passiert ist, war es ein native-Paket, das von Batch-Jobs seit Jahren erfolgreich eingesetzt worden war. Aber es war das erste Mal bei dieser Firma, dass sie von einem .NET Web-Service verwendet worden waren (die multithreaded ist). Das war es -. Sie über den Code ist Thread-sicher gelogen hatte

Ich hatte ein ähnliches Problem - und es tauchte ganz zufällig auf. Vielleicht war etwas korrupt in den Build-Dateien, aber ich landete es zur Festlegung der Projekt Reinigung zunächst dann wieder aufzubauen.

Also zusätzlich zu den anderen Antworten gegeben:

Welche Art von Dingen, können diese Fehler verursachen? Etwas korrupt in der Build-Datei.

Wie kann ich debuggen sie? Reinigen des Projekts und den Wiederaufbau. Wenn es behoben ist, war dies wahrscheinlich das Problem.

scroll top