Ich weiß, dass es bereits viele ähnliche Fragen und Antworten gibt, aber ich kann mein Problem nicht lösen.
In meiner großen Anwendung wird der Heap irgendwo beschädigt und ich kann ihn nicht finden. Ich habe auch Tools wie gflags verwendet, aber kein Glück.
Ich habe gflags auf dem folgenden Beispiel versucht, das den Heap absichtlich verdirbt:
%Vor%In Zeile # 2 wird der Heap überschrieben, aber wie man ihn mit Hilfe von Tools wie gflags, windbg usw. findet. Möglicherweise verwende ich die gflags nicht richtig.
Wenn dieselbe Variable konsistent beschädigt wird, können Sie mit den Datenumbrüchen schnell und einfach den für die Änderung verantwortlichen Code finden (sofern Ihre IDE dies unterstützt). (Debug- & gt; Neuer Unterbrechungspunkt- & gt; Neuer Datenhaltepunkt ... in MS Visual Studio 2008). Sie werden nicht helfen, wenn Ihre Heapkorruption zufälliger ist (aber ich dachte, ich würde die einfache Antwort teilen, falls es hilft).
Es gibt ein Tool namens Elektrozaun, von dem ich glaube, dass es auch unter Windows unterstützt wird.
Im Wesentlichen ist es das Entführen von malloc und co, um jede Zuweisung an der Seitengrenze zu beenden und die nächste Seite unzugänglich zu machen.
Der Effekt ist, dass Sie beim Pufferüberlauf einen seg-Fehler erhalten.
Es hat wahrscheinlich auch eine Option für Pufferunterlauf.
Bitte lesen Sie diesen Link Visual Studio - So finden Sie die Quelle von Heap-Korruptionsfehlern
Gibt es einen guten Valgrind-Ersatz für Windows?
Ermittelt Techniken zum Finden von Heap-Problemen in Windows.
Aber andererseits können Sie immer (wenn Sie neuen Code schreiben) Speicherverwalter schreiben. Der Weg ist: Verwenden Sie Ihre Wrapper-API, die malloc / calloc usw. aufrufen wird.
Angenommen, Sie haben api myMalloc (size_t len); Dann können Sie innerhalb Ihrer Funktion versuchen, HEADER + len + FOOTER zuzuweisen. Auf Ihrer Kopfzeile speichern Sie Informationen wie Größe der Zuordnung oder können weitere Informationen sein. Fügen Sie am Fuß eine magische Zahl wie Deadbeef hinzu. Und zurück ptr (von malloc) + HEADER von myMalloc.
Wenn du es mit myfree (void * ptr) frei machst, dann tu einfach ptr -HEADER, überprüfe die len und springe dann auf den FOOTER = ptr-HEADER + wirklich allocated len. Bei diesem Offset sollten Sie deadbeef finden, und wenn Sie nicht finden, dann ist es beschädigt.
Wenn automatisierte Tools (wie Elektrozaun oder Valgrind) nicht ausreichen und Sie Ihren Code aufmerksam betrachten, um herauszufinden, wo er möglicherweise schief gelaufen ist, hilft das nicht, und verschiedene Operationen werden deaktiviert / aktiviert (bis Sie erhalten eine Korrelation zwischen dem Vorhandensein von heap-corruption und den Vorgängen, die zuvor ausgeführt wurden oder nicht ausgeführt wurden, um es einzugrenzen, scheint nicht zu funktionieren. Sie können immer diese Technik ausprobieren, die versucht, die Korruption eher früher als später zu finden. um das Auffinden der Quelle zu erleichtern:
Erstellen Sie eigene benutzerdefinierte neue und löschen Sie Operatoren, die korruptionsoffene Schutzbereiche um die zugewiesenen Speicherbereiche herum platzieren, etwa so:
%Vor%... das oben Genannte wird ausreichen, um Ihnen die Funktionalität des Electric-Fence-Stils zu ermöglichen, indem Sie entweder in eines der beiden 64-Byte- "Guard-Bänder" am Anfang oder am Ende einer neuen / löschenden Speicherzuweisung schreiben Wenn die Zuordnung gelöscht wird, bemerkt MyCustomDelete () die Beschädigung und stürzt das Programm ab.
Wenn das nicht gut genug ist (z. B. weil zu dem Zeitpunkt, zu dem das Löschen auftritt, so viel passiert ist, weil die Korruption schwer zu sagen ist), können Sie noch weitergehen, indem MyCustomAlloc () den zugewiesenen Puffer hinzufügt in eine Singleton / global doppelt verknüpfte Liste von Zuordnungen, und MyCustomDelete () entfernen Sie es aus der gleichen Liste (stellen Sie sicher, diese Operationen zu serialisieren, wenn Ihr Programm Multithread ist!). Der Vorteil dabei besteht darin, dass Sie dann eine weitere Funktion hinzufügen können, die z. CheckForHeapCorruption (), das über diese verknüpfte Liste iteriert und die Schutzbänder jeder Zuordnung in der verknüpften Liste überprüft und meldet, wenn eine von ihnen beschädigt wurde. Dann können Sie im gesamten Code Aufrufe an CheckForHeapCorruption () streuen, so dass beim Auftreten von Heap-Fehlern beim nächsten Aufruf von CheckForHeapCorruption () statt später etwas mehr erkannt wird. Schließlich werden Sie feststellen, dass ein Aufruf von CheckForHeapCorruption () mit Bravour bestanden hat und der nächste Aufruf von CheckForHeapCorruption (), nur wenige Zeilen später, Korruption festgestellt hat. Zu diesem Zeitpunkt wissen Sie, dass die Korruption durch den Code verursacht wurde, der dazwischen ausgeführt wurde die beiden Aufrufe von CheckForHeapCorruption (), und Sie können dann diesen bestimmten Code untersuchen, um herauszufinden, was falsch ist, und / oder weitere Aufrufe von CheckForHeapCorruption () in diesen Code einfügen, falls erforderlich.
Wiederhole, bis der Fehler offensichtlich wird. Viel Glück!