Wie nach memory leaks suchen?



  • Hallo Leute,

    ich habe eine MFC Applikation , und arbeite mit VS2008. (Fragt bitte nich warum!? 🙂 )

    Nun habe ich beim schließen der App Memoryleaks:

    Detected memory leaks!
    Dumping objects ->
    {219931} normal block at 0x05C28D70, 2 bytes long.
     Data: <  > 03 00 
    {219909} normal block at 0x05C28D30, 2 bytes long.
     Data: <  > 03 00 
    {219520} normal block at 0x05C28CF0, 2 bytes long.
     Data: <  > 03 00 
    {219498} normal block at 0x05C28AD0, 2 bytes long.
    

    Nun konntet ich durch systematischen Ausschlussverfahren den Code finden der mit die fehler erzeugt. auch durch debuggen der ~ routine etc. weiß ich echt nich wo der fehler sein soll.

    Wie finde ich denn heraus Anhand der Ausgabe wo ich genau suchen'?

    Vielen Dank Euch



  • @SoIntMan
    Ist es denn ein Memory Leak? Kannst du diesen provozieren s.d. du einen stetig steigenden RAM Verbrauch hast?

    Ein Memory Leak am Programmende hört sich nach einer globalen Variablen an, welche nicht freigegeben wurde wie z.B. HBITMAP. Ist nicht weiter schlimm.

    Ich würde alternativ noch ein paar weitere Tools wie CppCheck und Dr. Memory drüber laufen lassen.



  • Anhand der Ausgabe findet man das meistens nur dann raus, wenn die Länge des allokierten Speichers eindeutig auf eine bestimmte Struktur hinweist. Ansonsten hilft es, einzelne Module ( z.B. Klassen ) deiner Software einzeln zu nutzen und auf MemoryLeaks zu prüfen und dich somit sukzessive ranzutasten.

    Desweiteren werden auch static-Objekte mitunter fälschlich verdächtigt, ein memory-leak zu verursachen.



  • Statische Codeanalyse kann helfen, cppcheck zB ist ganz gut darin, memory leaks zu finden.



  • Zudem sind Memory-Leaks mit steigender Erfahrung kein Problem mehr, wenn man sich eine saubere Art und Weise der Softwareentwicklung angewöhnt hat und mit den neuesten Standards arbeitet.



  • @It0101 sagte in Wie nach memory leaks suchen?:

    wenn man sich eine saubere Art und Weise der Softwareentwicklung angewöhnt hat und mit den neuesten Standards arbeitet.

    So wie VS2008?



  • @SoIntMan
    Du könntest DrMemory probieren: https://drmemory.org/
    Gerade mit älteren VS Versionen sollte das gut funktionieren. Idealerweise auch mit einem nicht zu aktuellen Windows. Im Falle des Falles einfach in einer VM mit ner älteren Windows Version laufen lassen.

    Damit bekommst du dann nicht nur Anzahl/Grösse/Inhalt der Leaks angezeigt, sondern jeweils auch wo die Allokation passiert ist (Callstack).



  • @Mechanics sagte in Wie nach memory leaks suchen?:

    @It0101 sagte in Wie nach memory leaks suchen?:

    wenn man sich eine saubere Art und Weise der Softwareentwicklung angewöhnt hat und mit den neuesten Standards arbeitet.

    So wie VS2008?

    Mit VS**** kenne ich mich leider nicht aus.

    Angefangen beim ersten "neuen" C++, nämlich mit c++11 meinte ich die Verwendung von smart-Pointer anstatt dem gewurschtel mit new und delete.
    Zeitlich danach kommt dann der Verzicht auf Smart-Pointer, wo es eben möglich ist und die Verwendung von std::move zum bewegen von Datenstrukturen.
    Des Weiteren meine ich sauberes Klassen-Design z.B. mit RAII, usw...



  • @It0101 Kleiner Tip: Visual Studio 2008 ist im Jahr (1x darfst du raten) 2008 rausgekommen (soll sein 2007 oder 2009, manchmal ist MS da ein Jahr daneben). Und C++11 im Jahr ...
    Und deswegen ...



  • @hustbaer sagte in Wie nach memory leaks suchen?:

    @SoIntMan
    Du könntest DrMemory probieren: https://drmemory.org/
    Gerade mit älteren VS Versionen sollte das gut funktionieren. Idealerweise auch mit einem nicht zu aktuellen Windows. Im Falle des Falles einfach in einer VM mit ner älteren Windows Version laufen lassen.
    Damit bekommst du dann nicht nur Anzahl/Grösse/Inhalt der Leaks angezeigt, sondern jeweils auch wo die Allokation passiert ist (Callstack).

    Super, vielen Dank ,das probiere ich doch einfach mal aus (ja habe dafür ne VM mit Win7 und VS2008)

    @Quiche-Lorraine sagte in Wie nach memory leaks suchen?:

    @SoIntMan
    Ist es denn ein Memory Leak? Kannst du diesen provozieren s.d. du einen stetig steigenden RAM Verbrauch hast?
    Ein Memory Leak am Programmende hört sich nach einer globalen Variablen an, welche nicht freigegeben wurde wie z.B. HBITMAP. Ist nicht weiter schlimm.
    Ich würde alternativ noch ein paar weitere Tools wie CppCheck und Dr. Memory drüber laufen lassen.

    Kann es denn auch was anderes sein außer ein memory leak ?? hmm ne globale variable ist es ehr nicht, und HBITMAP verwende ich an dieser stelle nicht.

    Ich probiere jetzt mal die zwei von euch erwähnten tools aus.

    @It0101: Wie schon in anderen Posts von mir erwähnt, komme ich bei manchen Projekten (retrofil, legancy-fit,brownfield) nicht um alte Tools drum herum. In der Industrie wird aus (never-touch-a-running-system) versucht so lange wie möglich auf die Technologien zu setzen weil es eben funktioniert. Und große Player wie Siemens sind da auch etwas träge.. wird alles seine Gründe haben.

    Und ja ich gebe mein besten um Sauber zu programmieren, ich konnte ja schon die 2 zeilen Code ermitteln welche ich aus kommentieren muss, um die leaks zu provizieren oder nicht.



  • Ok Cppcheck hat mir schon paar Hinweise😁

    Dr. Memory, funzt leider nicht, es komme 2 MessageBoxen: (bei ausführen in VS2008 durch Tools-> Menus )

    Unable to load client library: import MoveFileExW not found in KERNALBASE.dll.
    Unable to load client library: drmemorylib.dll: unable to process imports of client library.
    

    jemand hier noch ne Idee?

    Habe alle nach bestem Wissen der Anleitung nach gemacht und installiert



  • @It0101 sagte in Wie nach memory leaks suchen?:

    Angefangen beim ersten "neuen" C++, nämlich mit c++11 meinte ich die Verwendung von smart-Pointer anstatt dem gewurschtel mit new und delete.
    Zeitlich danach kommt dann der Verzicht auf Smart-Pointer, wo es eben möglich ist und die Verwendung von std::move zum bewegen von Datenstrukturen.
    Des Weiteren meine ich sauberes Klassen-Design z.B. mit RAII, usw...

    SmartPointer kann man seit C++98 und der Entwicklung der Boost.SmartPtr Klassen nutzen. Das hat damals schon sehr gut funktioniert. Dinge wie unique_ptr sind allerdings erst seit C++11 möglich. Meines Erachtens sollte es möglich sein, eine entsprechend alte Boost.SmartPtr Klasse mit einem alten MVC Compiler zu nutzen. Ganz schlimm sind nur die wirklich alten C++ Versionen von Microsoft.



  • @SoIntMan sagte in Wie nach memory leaks suchen?:

    Kann es denn auch was anderes sein außer ein memory leak ??

    Naja, sobald die Speicheranforderung kontinuierlich größer werden, hast du ein Memory Leak.

    Und sorry, ich muss nochmals nachfragen: Ist es definitiv ein Memory-Leak? Kannst du beispielsweise eine Aktion wiederholen und die Speicheranforderungen steigen stetig? Kannst du so z.B. 10MByte verballern?

    Ich habe nämlich schon einige angebliche Speicherlöcher gesehen, welche keine waren, sondern nur eine Eigenarten der C Runtime, Windows oder auch der WinAPI. Denn du nutzt die MFC, welche auf der WinAPI basiert. Und die WinAPI ist tückisch.

    Hast du den Visual Leak Detector for Visual C++ ausprobiert? Alternativ könntest du auch noch DebugDiag ausprobieren.



  • Du kannst einen Weekly-Build von Dr. Memory probieren. Oder eine andere Windows Version. Dr. Memory hat da leider manchmal Probleme die ich nicht ganz nachvollziehen kann. Die haben z.B. einen eigenen Loader drinnen mit dem sie ihre "Client DLL" laden. Warum auch immer, keine Ahnung. Und dieser Loader kann auf deinem OS wohl die Funktion MoveFileExW nicht finden.

    Du kannst auch einen Case hier aufmachen: https://github.com/DynamoRIO/dynamorio/issues



  • @SoIntMan sagte in Wie nach memory leaks suchen?:

    Unable to load client library: import MoveFileExW not found in KERNALBASE.dll.
    Unable to load client library: drmemorylib.dll: unable to process imports of client library.
    

    jemand hier noch ne Idee?

    Ich habe keine Ahnung von der Software, aber Windows hat meines Wissens keine KERNALBASE.dll sondern eine KernelBase.dll. Darin findet sich auch die MoveFileExW-Funktion, und dass bereits seit Windows XP. Sieht mir irgendwie nach einem Tippfehler in deiner Version aus. Schon etwas komisch, denn gerade bei so einem Fehler würde ich erwarten, dass er bei Tests sehr schnell auffällt. Probier's mal mit dem Vorschlag von @hustbaer, eine andere Version zu nehmen. Das schaut sehr danach aus, als wäre ein Bug-Report angebracht.

    P.S.: Scheint auch ein Beispiel für diese lustigen Fehlermeldungen zu sein, die einen öfter mal auf die falsche Fährte führen. Da wird einfach ein "catch all" gemacht und alle Fehler wie der einzige Fehler behandelt, den sich die Entwickler in dem Moment vorstellen konnten. Hier z.B. dass das Symbol MoveFileExW nicht in KERNALBASE.dll existiert. Dabei ist wohl der eigentliche Fehler, dass bereits die Datei nicht existiert. Kennt ihr diese Fehlermeldungen? Das ist hier noch ein sehr harmloses Beispiel, das geht auch schlimmer. Hab schon viel Zeit damit verschwendet, Fehlermeldungen wortwörtlich zu nehmen 😉



  • Einen wunderschönen Guten Morgen:)

    @Quiche-Lorraine sagte in Wie nach memory leaks suchen?:

    Naja, sobald die Speicheranforderung kontinuierlich größer werden, hast du ein Memory Leak.
    Und sorry, ich muss nochmals nachfragen: Ist es definitiv ein Memory-Leak? Kannst du beispielsweise eine Aktion wiederholen und die Speicheranforderungen steigen stetig? Kannst du so z.B. 10MByte verballern?
    Ich habe nämlich schon einige angebliche Speicherlöcher gesehen, welche keine waren, sondern nur eine Eigenarten der C Runtime, Windows oder auch der WinAPI. Denn du nutzt die MFC, welche auf der WinAPI basiert. Und die WinAPI ist tückisch.
    Hast du den Visual Leak Detector for Visual C++ ausprobiert? Alternativ könntest du auch noch DebugDiag ausprobieren.

    ich konnte das Memory-Leak lokalisieren (durch hinweise des cppckecks), also ja es war wirklich so, dass in ner loop (all 200ms, 2byte allokiert wurden aber nicht mehr frei gegeben wurden. Jetzt ist der Memory-Dump weg.

    @hustbaer sagte in Wie nach memory leaks suchen?:

    Du kannst einen Weekly-Build von Dr. Memory probieren. Oder eine andere Windows Version. Dr. Memory hat da leider manchmal Probleme die ich nicht ganz nachvollziehen kann. Die haben z.B. einen eigenen Loader drinnen mit dem sie ihre "Client DLL" laden. Warum auch immer, keine Ahnung. Und dieser Loader kann auf deinem OS wohl die Funktion MoveFileExW nicht finden.
    Du kannst auch einen Case hier aufmachen: https://github.com/DynamoRIO/dynamorio/issues

    ok dann probiere ich mal ein andere release aus... danke danke

    @Finnegan sagte in Wie nach memory leaks suchen?:

    Ich habe keine Ahnung von der Software, aber Windows hat meines Wissens keine KERNALBASE.dll sondern eine KernelBase.dll. Darin findet sich auch die MoveFileExW-Funktion, und dass bereits seit Windows XP. Sieht mir irgendwie nach einem Tippfehler in deiner Version aus. Schon etwas komisch, denn gerade bei so einem Fehler würde ich erwarten, dass er bei Tests sehr schnell auffällt. Probier's mal mit dem Vorschlag von @hustbaer, eine andere Version zu nehmen. Das schaut sehr danach aus, als wäre ein Bug-Report angebracht.

    das war ein Schreibfehler meinerseits "KERNALBASE.dll" ich habe den Text aus der MsgBox abgetippt.



  • Achje, ja, die tollen MessageBoxen wo Ctrl+C nicht funktioniert. Das sollte MS auch mal fixen.



  • Was mir noch aufgefallen ist, ich mache viel GID Kram in meiner MFC App, und mir war nicht klar,
    dass ich für jedes GDI Object .. hier CPen/CBrush.. die "DeleteObject" Method explizt aufrufen muss, dachte das mach dann deren Dtor... und Memory Dumpy bekam ich da auch nicht...

    CPen blackPen;
    blackPen.CreatePen(PS_SOLID,1,RGB(0,0,0));
    CBrush brush(atol(m_Data.GetAt(i-1,2)));
    Cpen* poldPen = pDC->SelectObject(&blackPen);
    CBrush * poldBrush= pDC->SelectObject(brush);
    ...
    
    pDC->SelectObject(poldPen );
    pDC->SelectObject(poldBrush );
    brush.DeleteObject();
    blackPen.DeleteObject();
    


  • @SoIntMan sagte in Wie nach memory leaks suchen?:

    und mir war nicht klar,
    dass ich für jedes GDI Object .. hier CPen/CBrush.. die "DeleteObject" Method explizt aufrufen muss, dachte das mach dann deren Dtor... und Memory Dumpy bekam ich da auch nicht...

    CPen blackPen;
    blackPen.CreatePen(PS_SOLID,1,RGB(0,0,0));
    CBrush brush(atol(m_Data.GetAt(i-1,2)));
    pDC->SelectObject(&blackPen);
    pDC->SelectObject(brush);
    ...
    brush.DeleteObject();
    blackPen.DeleteObject();
    

    Wieso meinst du dass du das musst bzw. dass der von dir gezeigte Code korrekt ist?

    Soweit ich weiss sollte das eher so aussehen:

    CPen blackPen;
    blackPen.CreatePen(PS_SOLID,1,RGB(0,0,0));
    CBrush brush(atol(m_Data.GetAt(i-1,2)));
    CPen* originalPen = pDC->SelectObject(&blackPen);
    CBrush* originalBrush = pDC->SelectObject(&brush);
    ...
    pDC->SelectObject(originalPen);
    pDC->SelectObject(originalBrush);
    

    Siehe https://docs.microsoft.com/en-us/cpp/mfc/selecting-a-graphic-object-into-a-device-context?view=msvc-160



  • @hustbaer sagte in Wie nach memory leaks suchen?:

    Wieso meinst du dass du das musst bzw. dass der von dir gezeigte Code korrekt ist?
    Soweit ich weiss sollte das eher so aussehen:

    CPen blackPen;
    blackPen.CreatePen(PS_SOLID,1,RGB(0,0,0));
    CBrush brush(atol(m_Data.GetAt(i-1,2)));
    CPen* originalPen = pDC->SelectObject(&blackPen);
    CBrush* originalBrush = pDC->SelectObject(&brush);
    ...
    pDC->SelectObject(originalPen);
    pDC->SelectObject(originalBrush);

    Siehe https://docs.microsoft.com/en-us/cpp/mfc/selecting-a-graphic-object-into-a-device-context?view=msvc-160

    ja siehe oben, das habe ich noch vergessen im code-snipped (SelectObject(orgObjects).. aber trotzdem mit DeleteObject

    https://forums.codeguru.com/showthread.php?115114-CPen-CBrush-DeleteObject-minimizing-memory-leaks-and-releasing-resources

    EDIT: hmmm.. was is nun richtig....!?


Anmelden zum Antworten