Wie nach memory leaks suchen?



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

    Die schreiben doch auch dass das DeleteObject nicht nötig ist:

    Not that it makes much difference (I consider it good style to call CGdiObject::DeleteObject explicitly) but the destructor for the individual object types will delete the object automatically.
    Therefore there is no actual need to call DeleteObject if you're declaring a local GDI object inside a loop (providing you remember to deselect it from the DC first) as it will be called automatically when the object goes out of scope.

    Gut, der meint dass er es "good style" findet trotzdem selbst DeleteObject aufzurufen. Ich bin da ganz anderer Meinung. Ich finde dass das ganz schlechter Stil ist. Unnötiger Code bremst bloss beim Lesen und ist - gerade für Leute die sich noch nicht perfekt mit dem verwendeten Framework auskennen - verwirrend/schädlich. Weil man normalerweise halt nicht davon ausgeht dass jemand was hinschreibt was völlig redundant ist. Und daher kann man dann schnell annehmen, dass es halt nicht redundant ist. Was ja wie gesagt nicht stimmt.
    Darüber ob die Objekte jetzt automatisch gelöscht werden oder nicht besteht aber kein Zweifel. Das steht da auch klar in dem Thread dass sie das werden.

    Danke , ja ich finde das auch kein guter Stil, nix desto trotz habe ich es einfach mal so gemacht, um in meinen WnCE build die memory leak problematik einzugrenzen.

    @Foulpelz sagte in Wie nach memory leaks suchen?:

    wenn ein prozess beendet wird, erlischt auch sein virtueller adressraum.
    d.h ein normales windows-programm kann üblicherweise keine memLeaks erzeugen, die das ganze system beeinträchtigen.

    Doch, genau das geschieht:) Meine Anwendung ließt zyklisch Mess-Daten via Tcp/ip und zeigt diese Daten dann via GDI gemale an:) Und wenn ich das Ganze dann ne Nacht laufen lasse (auf WinCE) erscheint ne Meldung Memory low.. alle anderen Anwendung sind eingefroren etc. Nichts geht mehr..

    Das Problem ist, dass ich aber keine Memory leaks bzw. keine Dumps (beim beenden der Anwendung ) mehr bekomme, wenn ich sie auf Win32 system im Debugger kompiliert laufen lasse.

    Ich verwendet quasi die selbe Codebase als ein CDialogHost, welches ich einmal in Win32 App und einmal in WinCE App verwenden/kompilieren kann.

    Leider habe ich vermutlich immer noch memory-leaks.. aber das kann ich schlecht auf dem WinCE device debuggen, ich ging mal davon aus dass wenn ich keine memoryDumps im Win32 target mehr bekomme ich dann in WinCE gut weg komme.. aber falsch gedacht😅



  • @SoIntMan Hast du immer noch ein Leak? Oder ist nun Ruhe?



  • Ich habe ein kleines Tool geschrieben hier , einfach:

    • Kopiere MemoryLeakManager.hpp Header
    • #include "MemoryLeakManager.hpp"
    • am anfang deine Programm schreibe:
    int dummy = 0;
    g_stackTop = &dummy;
    
    • am ende aufruf:
    CollectGarbage();
    

    das Tool wird dir sagen, wo du Memory Leak gemacht hast.



  • @muazsh

    #define new new(__FILE__, __LINE__)
    

    Mit nem #define für new kann das die MSVC Runtime auch selbst.
    Einfach

    #ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif
    

    in alle .cpp Files nach allen #includes reinschreiben, und passt.

    ps: Dein Code ist nicht Thread-safe.



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

    @SoIntMan Hast du immer noch ein Leak? Oder ist nun Ruhe?

    Hi Hustbear, ich weiß es nicht 😞 also wie erwähnt bekomme ich keine Memory Dumps mehr (kann das ja nur in der Win32 Debug vs2008 Output sehen)
    Wenn ich dann auf das Target auf WinCE release ARM wechsel und das auf dem WinCE gerät Laufen lasse (über 24h) dann läuft mir der Speicher voll, aber ich habe auf WinCE keine diagnose tools um das zu prüfen.

    Weißt Du, Kennst du ein Diagnose Tool für WinCE um sowas zu prüfen?:)

    EDIT: hmm .. vll. hilft mir das https://sourceforge.net/projects/crtdbg4wince/ weiter

    @muazsh sagte in Wie nach memory leaks suchen?:

    Ich habe ein kleines Tool geschrieben hier , einfach:

    Kopiere MemoryLeakManager.hpp Header
    #include "MemoryLeakManager.hpp"
    am anfang deine Programm schreibe:

    int dummy = 0;
    g_stackTop = &dummy;

    am ende aufruf:

    CollectGarbage();

    das Tool wird dir sagen, wo du Memory Leak gemacht hast.

    hammer danke, ABER damit kann ich dann auch nur in der Win32 Target leaks suchen, finde ich da mehr als der Vs2008 Memory Dump?



  • Wenn du auf WinCE einen Memory Leak hast, wirst du den auch in den Win32 Targets haben.
    Es kann natürlich auch sein, das freigegeben würde, aber das zu spät passiert (ist mir mal beim laden von Frames aus 'nem Video Stream passiert). Das ist dann kein Leak im klassichen Sinn, macht aber keinen Unterschied, weil der Speicher trotzdem irgendwann voll ist.

    Was mir spontan einfallen würde, ist: Mit GetProcessMemoryInfo für Windows an verschiedenen Stellen Informationen zum Speichererbrauch deines Prozesses auszulesen und in ein log File zu schreiben.

    Oder, testweise einen eigenen Memory Manager einhängen, und new und delete überschreiben. Da könntest du auch den Speicher so beschränken, dass du mit dem Win32 Target in das selbe Problem läufst, wie auf WinCE. Und, im Überlauf fall, könntest du einen Stacktrace ausgeben lassen (z.B. mit https://www.boost.org/doc/libs/1_66_0/doc/html/stacktrace/getting_started.html#stacktrace.getting_started.how_to_print_current_call_stack)



  • Wieviel RAM hat den das WinCE Gerät?

    Wenn es z.b. nur 1GB Ram hat und aber auf deinem Development Maschine das ganze nach 24h mehr als 1GB Ram braucht dann hast du einen Hinweis was los ist.



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

    hammer danke, ABER damit kann ich dann auch nur in der Win32 Target leaks suchen, finde ich da mehr als der Vs2008 Memory Dump?

    Nein, weniger.



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

    Wenn du auf WinCE einen Memory Leak hast, wirst du den auch in den Win32 Targets haben.

    ok das is beruhigend:) ich logge einfach mal die speicherverbrauch mit.

    @firefly sagte in Wie nach memory leaks suchen?:

    Wieviel RAM hat den das WinCE Gerät?
    Wenn es z.b. nur 1GB Ram hat und aber auf deinem Development Maschine das ganze nach 24h mehr als 1GB Ram braucht dann hast du einen Hinweis was los ist.

    das ding hat 200MB Ram. Also nich viel.

    @hustbaer sagte in Wie nach memory leaks suchen?:

    @SoIntMan sagte in Wie nach memory leaks suchen?:

    hammer danke, ABER damit kann ich dann auch nur in der Win32 Target leaks suchen, finde ich da mehr als der Vs2008 Memory Dump?

    Nein, weniger.

    Bedeutet es denn dass wenn ich keine "Memory-dumps" bekomme, Ich memory Leaks frei bin?



  • Process Hacker ist auch noch ein interessantes Tool, das den Windows Task Manager ersetzt. Damit kann man sich detaillierte Eigenschaften eines Prozesses anschauen und in der Statistik gucken, ob einem zB Windows Handles weglaufen. Damit hat man zumindest einen Indiz auf die Ursache eines Resource Leaks.



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

    @hustbaer sagte in Wie nach memory leaks suchen?:

    @SoIntMan sagte in Wie nach memory leaks suchen?:

    hammer danke, ABER damit kann ich dann auch nur in der Win32 Target leaks suchen, finde ich da mehr als der Vs2008 Memory Dump?

    Nein, weniger.

    Bedeutet es denn dass wenn ich keine "Memory-dumps" bekomme, Ich memory Leaks frei bin?

    Nein. Es bedeutet nur dass das was @muazsh programmiert hat weniger findet als der MSVC Debug Heap. (MSVC findet z.B. malloc Leaks, das von @muazsh wenn ich mich nicht irre nicht.)
    Der Debug Heap findet aber auch nicht alles. Der findet nur Leaks von Zeugs was im CRT Heap liegt und über CRT Funktionen bzw. new angefordert wurde. Nicht also Speicher der direkt mit z.B. HeapAlloc angefordert wurde, keine Handle Leaks usw.

    Dr. Memory dagegen findet das meiste von diesen Dingen auch. Weswegen ich an deiner Stelle auch versuchen würde Dr. Memory zum Laufen zu bekommen.



  • @hustbaer mein Tool ist nicht nur für Windows gedacht, sondern auch für andere Plattformen deswegen kann nicht DEBUG_NEW benutzen, und ja du hast recht es ist nicht thread safe und es sollte vorsichtig mit Multithread-Anwendungen verwendet werden.
    Eine weitere Annahme, die ich gemacht habe, ist ein kontinuierlicher Stack Space, der nicht dem Standard entspricht, aber so aussieht, als ob die meisten Implementierungen folgen.
    TLDR: Mein Tool ist einfach, aber nicht optimal.



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

    @hustbaer mein Tool ist nicht nur für Windows gedacht, sondern auch für andere Plattformen deswegen kann nicht DEBUG_NEW benutzen,

    Dein Tool nicht, aber @SoIntMan kann DEBUG_NEW benutzen 😉

    und ja du hast recht es ist nicht thread safe und es sollte vorsichtig mit Multithread-Anwendungen verwendet werden

    Ich würde sagen es sollte gar nicht mit Multithread-Anwendungen verwendet werden 🙂

    Eine weitere Annahme, die ich gemacht habe, ist ein kontinuierlicher Stack Space, der nicht dem Standard entspricht, aber so aussieht, als ob die meisten Implementierungen folgen.

    Ich kenne kein System auf dem der Stack nicht "am Stück" liegen würde. Was den (C++?) Standard angeht: der C++ Standard definiert soweit ich weiss gar nichts zum Thema Stack. Der kennt nur "automatic storage" - wie das umgesetzt ist ist dann ein Implementierungsdetail. Ich kenne aber auch keine Implementierung in der es nicht mittels Stack gelöst wäre.

    Ich frage mich aber sowieso wozu dieser Stack-Scanner gut ist. Der findet zwar direkte Zeiger im Stack, aber keine indirekten. Sobald man also einen Zeiger auf irgendwas am Stack liegen hat, was selbst wieder Zeiger enthält, würde dein Tool ja erst wieder Leaks reporten.
    Also mit einem std::vector<int> am Stack ginge es noch. Mit einem std::vector<std::string> bekäme man dann schon falsche Leaks reportet.



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

    Weswegen ich an deiner Stelle auch versuchen würde Dr. Memory zum Laufen zu bekommen.

    Das hier. Es ist wirklich dermaßen nützlich bei (wenn man es mal überprüfen möchte) auch akzeptabler Geschwindigkeit.

    Leider habe ich VS 2008 nicht mehr hier, allerdings hatte ich auch bei VS 2010 und Windows 10 keinerlei Probleme.



  • @hustbaer Ich möchte mein Tool nicht befürworten, als es ist experimentelles Tool, aber Profiling ist keine leichte Aufgabe, und es gibt kein Tool, das Hexe macht, also doch das Tool funktioniert auch mit Multithread-Anwendungen aber man sollte wissen wie man es benutzt.
    Danke für die indirekt Zeiger Punkt, werde ich bald beheben.



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

    @hustbaer Ich möchte mein Tool nicht befürworten, als es ist experimentelles Tool, aber Profiling ist keine leichte Aufgabe,

    Profiling?

    und es gibt kein Tool, das Hexe macht,

    Hexe? 🙂 Ich versteh immer weniger.
    Meinst du es gibt nix was thread-safe wäre und viel mehr findet als dein Tool? Das mag stimmen wenn du etwas suchst was auf jeder Plattform läuft. Aber Tools wie eben Dr. Memory oder valgrind sind schon ziemlich mächtig. Und definitiv thread-safe. Wenn man aktuelle GCC, Clang oder MSVC Versionen verwenden kann auch Address-Sanitizer.

    also doch das Tool funktioniert auch mit Multithread-Anwendungen aber man sollte wissen wie man es benutzt.

    Er. Wenn es nicht Thread-safe ist, wie soll es dann mit Multithreaded-Anwendungen funktionieren? Ich meine ja, "funktionieren" wird es schon. Mit Glück. Bis es dann halt nicht mehr funktioniert, z.B. weil es das Programm zum Crashen bringt.

    Danke für die indirekt Zeiger Punkt, werde ich bald beheben.

    Je mehr Objekte du als "kein Leak" klassifizierst, desto mehr false negatives wird dein Tool haben. Der Speicher wird ja vom Destruktor nicht überschrieben. D.h. wenn ich eine Klasse Foo habe die Speicher besitzt, aber den Dtor vergesse (bzw. den Speicher im Dtor nicht freigebe und auch den Zeiger nicht auf 0 setze)...
    Wenn ich dann einen vector<Foo> mache, und diesen dann verkleinere...
    Dann bleibt im Vektor ein Zeiger auf das Array Foo Array. Der Speicherbereich wird durch das verkleinern des Vektor ja nicht kleiner. Dann scannst du den, findest die Zeiger in den bereits zerstörten Foo Objekten, und klassifizierst das als "kein Leak".



  • @hustbaer
    das meinte ich mit Profiling Speichernutzung Abschnitt 🙂
    Beim Hexe meinte ich Hexerei, vielleicht ist mein Deutsch nicht perfekt wie mein Tool 🙂 aber ich höre Leute sagen "Das macht keine Hex" oder etwas ähnlich als Ersatz für "es ist keine Magie".

    für Multithread-Anwendungen sollte man definieren, wo jede skeptische Thread-Logik beginnt und endet und dann das machen, was ich in meinem allerersten Post erwähnt habe.

    Nur das Setup (ohne zu analysieren) von Valgring und ähnlichen Tools ist echt Kopfschmerz und ich weiß nicht wie es bei großen anwendungen geht, mit meinem Tool kann man die Anwendung teilen aufteilen und jede Aufteilung einzeln analysieren, und deshalb habe ich mein kleines Tool geschrieben.



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

    @hustbaer
    das meinte ich mit Profiling Speichernutzung Abschnitt 🙂

    Ah, verstehe! Kann dein Tool auch Memory-Profiling? (Also im Sinn von "wo/wofür wird wie viel Speicher verbraucht"?)

    Beim Hexe meinte ich Hexerei, vielleicht ist mein Deutsch nicht perfekt wie mein Tool 🙂 aber ich höre Leute sagen "Das macht keine Hex" oder etwas ähnlich als Ersatz für "es ist keine Magie".

    Danke für die Erklärung! Ich bin Österreicher. "Keine Hexerei" versteh ich, abgekürzt wird das hierzulande aber nicht. Daher war ich mir nicht sicher.

    für Multithread-Anwendungen sollte man definieren, wo jede skeptische Thread-Logik beginnt und endet und dann das machen, was ich in meinem allerersten Post erwähnt habe.

    Sorry, check ich nicht. Macht aber nix, ich muss nicht alles verstehen 🙂

    Nur das Setup (ohne zu analysieren) von Valgring und ähnlichen Tools ist echt Kopfschmerz

    Auf den meisten Distris einfach:
    sudo apt install valgrind
    Ansonsten: repo klonen und selbst bauen ist auch nicht so schwer. Musste ich machen um das Ding unter WSL zum Laufen zu bekommen. Ein paar Minuten, mehr hat das nicht gedauert.

    Dr. Memory ist ... leider etwas "hit and miss". Wenn Dr. Memory sich mit der verwendeten Windows Version verträgt, dann ist Dr. Memory mMn. so einfach zu verwenden wie es nur geht.

    und ich weiß nicht wie es bei großen anwendungen geht, mit meinem Tool kann man die Anwendung teilen aufteilen und jede Aufteilung einzeln analysieren, und deshalb habe ich mein kleines Tool geschrieben.

    Also abgesehen davon dass valgrind (sehr) langsam ist, verträgt es sich schon ganz gut mit grossen Anwendungen. Dr. Memory auch.

    Mein Tip wäre aber wo es geht Address Sanitizer zu verwenden. Da reicht es einfach mit dem Switch -fsanitize=address zu bauen und dann das Programm bzw. einen Unit-Test zu starten. Gefundene Probleme werden dann einfach auf stderr ausgegeben. Wenn der Compiler mit dem man arbeitet es unterstützt also so ziemlich das einfachste was Setup angeht. Und das Ding ist extrem gut. Das Programm wird davon natürlich auch gebremst, aber lange nicht so extrem wie von Valgrind. Die Qualität der Diagnostics ist auch extrem gut.

    Für den OP ist Address Sanitizer halt leider keine Option, da er VS 2008 verwendet, und VS Address Sanitizer nicht unterstützt. Daher meine Empfehlung Dr. Memory zu verwenden. Auch sehr mächtig, wenn man es zum Laufen bekommt.



  • @hustbaer ich habe meinen Standpunkt dargelegt, schön, dass ich mit dir diskutiert habe.



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

    @hustbaer sagte in Wie nach memory leaks suchen?:

    Weswegen ich an deiner Stelle auch versuchen würde Dr. Memory zum Laufen zu bekommen.

    Das hier. Es ist wirklich dermaßen nützlich bei (wenn man es mal überprüfen möchte) auch akzeptabler Geschwindigkeit.
    Leider habe ich VS 2008 nicht mehr hier, allerdings hatte ich auch bei VS 2010 und Windows 10 keinerlei Probleme.

    Back to the roots , Dr. Memory:)

    Ich habe ein VM Win7, darin VS2008 und der Dr. Memory V2.5... und auch mal die V2.4 verwendet.. mehr kann ich von der Homepage nicht bekommen ..

    <Application z:\Sources\WinCE_Development\Ms3ControlsApp_TP1xxx\Output\Ms3ControlsApp\Win32\Debug\Ms3ControlsApp.exe (2560). Unable to load client library: import MoveFileExW not found in KERNELBASE.dll.>
    <Application z:\Sources\WinCE_Development\Ms3ControlsApp_TP1xxx\Output\Ms3ControlsApp\Win32\Debug\Ms3ControlsApp.exe (2560). Unable to load client library: drmemorylib.dll: unable to process imports of client library..>
             WARNING: unable to locate results file: can't open C:\Users\admin\AppData\Roaming\Dr. Memory/resfile.2560 (code=2).
    Dr. Memory failed to start the target application, perhaps due to
    interference from invasive security software.
    Try disabling other software or running in a virtual machine.
    WARNING: Examine the following unusual libraries in this process to help identify
    invasive software that may have affected the target application:
    
    	C:\Windows\system32\api-ms-win-crt-private-l1-1-0.dll
    	C:\Windows\system32\api-ms-win-crt-runtime-l1-1-0.dll
    	C:\Windows\system32\api-ms-win-crt-locale-l1-1-0.dll
    	C:\Windows\system32\api-ms-win-core-file-l1-2-0.dll
    	C:\Windows\system32\api-ms-win-crt-time-l1-1-0.dll
    	C:\Windows\system32\api-ms-win-core-localization-l1-2-0.dll
    	C:\Windows\system32\api-ms-win-core-processthreads-l1-1-1.dll
    	C:\Windows\system32\api-ms-win-core-timezone-l1-1-0.dll
    	C:\Windows\system32\api-ms-win-core-file-l2-1-0.dll
    	C:\Windows\system32\api-ms-win-core-synch-l1-2-0.dll
    	C:\Windows\system32\api-ms-win-crt-string-l1-1-0.dll
    
    Please file a bug about this at http://drmemory.org/issues
             WARNING: application exited with abnormal code 0xffffffff
    

    Das is der output der mir Dr. Memory liefert (wie schon die ersten beiden Zeilen erwähnt. KERNEL dll usw.) was könnte nich noch tun!?


Anmelden zum Antworten