Visual Leak Detector ohne Callstack
« | 15 Mar 2020 | »Und alle paar Monate das gleiche Problem:
Verdammt, den Fehler kenne ich … das hatte ich schon mal … Wie war noch gleich die Lösung?
Unsere heutige Episode aus der Serie Was ich mir merken sollte heißt: “Visual Leak Detector ohne Callstack”
Die erste Lektion heißt:
Voraussetzung: Immer die neueste Version installieren
Wenn man auf vielen Maschinen arbeitet, kommt es schon mal vor, dass
man z.B. für Windows 7
eine Version herunterlädt (oder geladen und abgelegt hat), die super
funktioniert.
Doch die gleiche Version produziert unter Windows 10
Crashes beim Start eines Programms.
Die Lösung: Neueste Version installieren
Denn mit jeder neuen Version von Visual Studio, der C Runtime oder dem Betriebssystemkern sind Anpassungen am Leak-Detector erforderlich. Das Teil “hackt” sich schließlich zwischen die APIs um Fehler zu finden, wenn da was nicht passt, wird das Tool ungewollt zur Malware, die jede Menge undefiniertes Verhalten und seltsame Crashes produzieren kann.
Problem: Keine Debug Infos beim Callstack vorhanden
Das “geilste” Feature des Leak Detectors ist, dass er am Ende des Programms den Allokierungs-Callstack des Leaks anzeigt (weil er den immer brav mitloggt).
Und eben diese Aufrufliste wird mit Quellcode-Datei und Zeilennummer schön ordentlich ausgegeben, damit Visual Studio per Doppelklick sofort zur Leak-Zeile springen kann.
Das funktionierte von Studio 2005 bis 2012 “out-of-the-box”. Doch seit Studio 2015 werden zwar Code-Adressen angezeigt, der Verweis zur Quelldatei fehlt aber … folglich hilft einem die Info recht wenig.
Es sieht dann so aus:
1WARNING: Visual Leak Detector detected memory leaks! 2---------- Block 290 at 0x000000003222D1C0: 100 bytes ---------- 3 Leak Hash: 0x47A1C106, Count: 1, Total 100 bytes 4 Call Stack (TID 11700): 5 ntdll.dll!RtlAllocateHeap() 6 vbincopy.exe!0x00007FF68312B5AA() 7 vbincopy.exe!0x00007FF68312B32D() 8 vbincopy.exe!0x00007FF68312EF9F() 9 vbincopy.exe!0x00007FF6830E0F3E()
Lösung: Debug Info VOLLSTÄNDIG generieren
Kurz gesagt:
Man muss bei den
Project Properties
unterLinker
-Debugging
-Generate Debug Info
die Option
Generate Debug Information optimized for sharing and publishing
aktivieren oder den Switch/DEBUG:FULL
anfügen.
In den neueren Studio-Versionen wurde ein neues verkleinertes Format für die guten alten PDB Dateien als Standard eingeführt.
Damit kann der Detector nicht mehr Datei und Zeilennummer auflösen. Mit der genannten Einstellung funktioniert aber wieder alles wie gewohnt.
… und es sieht dann so aus:
1WARNING: Visual Leak Detector detected memory leaks! 2---------- Block 290 at 0x00000000736EE2D0: 100 bytes ---------- 3 Leak Hash: 0x36F1F623, Count: 1, Total 100 bytes 4 Call Stack (TID 16100): 5 ntdll.dll!RtlAllocateHeap() 6 new_array.cpp (29): vbincopy.exe!operator new[]() 7 vbincopy.cpp (141): vbincopy.exe!gate::VBinCopy::Form_Closed() + 0xA bytes 8 delegates.hpp (278): vbincopy.exe!gate::Delegate2<gate::ui::Form *, 9 gate::ui::EventArg *>::method_dispatcher_impl<gate::VBinCopy>() 10 delegates.c (37): vbincopy.exe!gate_delegate_invoke() + 0x14 bytes
Ah, eine Allokation in Form_Closed()? Wozu denn das?
Fazit
Bin gespannt, wie lange es jetzt dauert, bis ich wieder vor einem “nicht funktionierenden” Leak Detector stehe und mich wieder frage: “Warum?”
Es wäre eine Überlegung wert die Option /DEBUG:FULL
durch CMake hinzuzufügen.
Aber letztendlich nutze ich für die aktive Entwicklung im GATE Projekt
ohnehin meine selbst erstellten Projektdateien, weil ich nicht immer CMake
bemühen möchte, wenn ich 2 neue Dateien hinzufüge.
Und damit bleibt die Frage weiter aktiv:
Wie lange wird es wohl dauern, bis ich diese Einstellung wieder vergesse.