Seite 1 von 1

Speicherfresser mittels Debugger finden

Verfasst: 16.03.2021 22:33
von jacdelad
Hallo,
ich brauche mal einen weißen Rat zum Debugger. Ich habe ihn bisher nur rudimentär genutzt, deshalb Steg ich bei der Bedienung auf dem Schlauch.
Ich habe ein Programm das aus 31 Rechnern ausgeführt wird und dort ein paar Dinge überwacht und per Netzwerk kommuniziert. Auf 30 Rechnern läuft es problemlos, aber auf einem benutzt es mit der Zeit immer mehr RAM und vermutlich auch andere Ressourcen, was soweit geht, dass andere Programme den Start wegen Ressourcenmangels verweigern, sogar der Taskmanager. Deshalb würde ich gern per Debugger herausfinden wo das Leck ist, aber ich komme nicht so richtig damit klar.

Re: Speicherfresser mittels Debugger finden

Verfasst: 17.03.2021 01:56
von Axolotl
Hallo jacdelad,

ich nutze fast nur den Debug Befehl. Häufig im Macro wie unten.

Code: Alles auswählen

Macro DQ
"
EndMacro
Macro RectToText(rcRect, sSep=", ")    ;­ sSep separated text 
  Str(rcRect\left) + sSep + Str(rcRect\top) + sSep + Str(rcRect\right) + sSep + Str(rcRect\bottom)
EndMacro 
Macro InspectRect(rcRect)  
  DQ#rcRect#DQ + " = " + RectToText(rcRect) 
EndMacro 
; irgendwo im code wenn es um ein rc.RECT geht, wie beispielsweise bei GetWindowRect_()
Debug InspectRect(rc) 

Um den Überblick zu behalten kann man in den Macros noch mit den #PB_Compiler_* Constanten hilfreiche Infos einbinden.

Code: Alles auswählen

Macro DebugEx(sText) 
  Debug sText + " - " + #PB_Compiler_Procedure + "()" 
EndMacro 
Jetzt ein paar Vorschläge, direkt aus der Hüfte....
Generell programmiere ich immer defensiv. D.h. Alle zurückgegebenen Werte von Proceduren werden auf Fehler ausgewertet und durch Debug (manchmal auch durch Eigenkonstruktion LogWrite()) angezeigt.

Wenn man Speicher oder Ressourcen allociert dann auch wieder freigeben und das Verhalten gemäß oben prüfen!

Für deinen Fall könnte auch der "Remote debugging with the standalone debugger" eine spannende Konfiguration sein. (Da bin ich aber nicht intensiv genug eingestiegen.)

Besser kann ich jetzt spontan nicht helfen. Ggf. kommt ja noch einer der Profis mit ein paar Ideen.

Re: Speicherfresser mittels Debugger finden

Verfasst: 17.03.2021 03:16
von Dadido3
Der Debugger alleine ist nicht sonderlich hilfreich beim aufspüren von Speicherlecks von dynamischen Speicherbereichen.

Ich habe für diesen Fall mal ein >> Include << geschrieben welches jeden der folgenden Aufrufe überwacht:
  • AllocateStructure (Im Programm müss alle Vorkommnisse von AllocateStructure mit _AllocateStructure ersetzt werden. Das betrifft aber nur AllocateStructure!)
  • FreeStructure
  • AllocateMemory
  • ReAllocateMemory
  • FreeMemory
Dabei wird alle 10 Sekunden eine Liste mit reservierten Speicherbereichen über den Debugger ausgegeben. Auch wird gemeldet, wenn versucht wird einen zuvor gelöschten oder unbekannten Speicherbereich nochmals zu löschen oder dessen größe zu verändern.

Um es zu verwenden, einfach am Anfang deines Programmes inkludieren oder reinkopieren. Wenn die ausgegebene Liste mit der Zeit immer größer wird, dann hast du mit ziemlicher Sicherheit ein (selbstgemachtes) Speicherleck. Mit Hilfe der ausgegebenen Liste kann man dann relativ einfach die Zeile von AllocateStructure bzw. AllocateMemory finden, dessen Speicher vergessen wurde freizugeben.

Natürlich setzt das voraus, dass dein Problem durch nicht mehr gelöschte dynamische Speicherbereiche entsteht. Falls du andere dynamische Ressourcen reservierst (z.B. Bilder) hilft das Include nicht beim Aufspüren von deren Speicherlecks, aber es ließe sich dahingehend erweitern. Für Listen und Maps kannst du natürlich die Anzahl der Elemente direkt im Debugger ermitteln.

Der Code hat noch Luft für Verbesserungen. Man könnte noch zusätzlich zur Zeilennummer den Namen des aktuellen Quellcodes speichern. Auch ist die Ausgabe durch den Debugger eventuell ungünstig, aber es ist nicht allzu schwer die Ausgabe in eine Datei umzubiegen. Ich hoffe der Code hilft, wenn auch nur als Basis.

Re: Speicherfresser mittels Debugger finden

Verfasst: 17.03.2021 10:45
von jacdelad
Ah danke, das werde ich mal ausprobieren. Irgendwo muss ich ja anfangen und je mehr ich ausschließen kann desto enger wird der Kreis der Verdächtigen.

Re: Speicherfresser mittels Debugger finden

Verfasst: 17.03.2021 17:19
von jacdelad
Ich habe tatsächlich einen Abschnitt gefunden, bei dem ein Speicher reserviert und unter bestimmten Umständen nicht freigegeben wurde. Vielleicht war das schon alles.

Die pbi von @Dadido3 geht auch ganz gut, simpel und schlicht. Ich hab sie minimal angepasst, damit man bei der Übergabe eines zweiten Parameters bei AllocateMemory keine Fehlermeldung bekommt.

Vielen Dank.

Re: Speicherfresser mittels Debugger finden

Verfasst: 23.03.2021 14:16
von jacdelad
Das Problem scheint noch nicht ganz gefixt zu sein.

Ich weiß, dass ich per Windows-API auslesen kann welche Objekte ich im Speicher hab und wie groß die sind. Gibt es da schon einen vorgefertigten Quelltext?