Speicherlecks und Allocation Numbers


Thomas Wölfer
Thomas Wölfer

28. April 2005


So nett das alles ist mit dem Managed Code - letzten Endes gibt es noch jede Menge unmanaged Code der gewartet und verwendet werden will. In Fall unseres aktuellen Projektes - das eigentlich ein managed Code Projekt ist - gibt es zum Beispiel einige Megabyte an nativem Win32 C++ Code. Dabei handelt es sich um Libraries die Ihren Dienst tun, und bei denen es schlicht keinen Sinn macht, sie zur CLR zur portieren.

Das bedeutet auch, das man sich eben auch weiterhin mit Speicherlecks in normalen Win32 Code auseinandersetzen muss. Dazu gibt es den extrem hilfreichen Debug-Heap und im Fall von MFC Code die zugehörigen Wrapper wie zum Beispiel das CMemoryState Objekt. Mit einem CMemoryState kann man zum Beispiel die momentan allozierten Objekte anzeigen lassen, oder man kann eine Statistik der Allokationen erhalten. ( Um die seit einem gegebenen Zeitpunkt allozierten Speicherbereiche zu finden, muss man zunächst einen Checkpoint() durchführen, und vom zugehörigen Objekt dann DumpAllObjectsSince() aufrufen.)

Dabei zeigt einem die CRT dann neben den Allocationen (wenn möglich mit Dateiname und Zeilennummer) auch eine 'Allocation Number' an. Dabei handelt es sich um die Nummer der Allocation im laufenden Programm. Diese Nummern sind ganz interessant - das Problem ist aber: Wie findet man nun heraus, welcher Vorgang eine gegebene Allokation ausgelöst hat.

Das geht am einfachsten mit _CrtSetBreakAlloc(). Man übergibt der Funktion die Nummer der Allocation aus dem Dump - und startet den Debugger. Der bleibt dann bei dieser Allokation stehen - und man kann einfach per Call-Stack herausfinden, was den Vorgang ausgelöst hat.