Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Speicherleaks finden mit FastMM4 (https://www.delphipraxis.net/204608-speicherleaks-finden-mit-fastmm4.html)

Shark99 11. Jun 2020 01:43

Delphi-Version: 7

Speicherleaks finden mit FastMM4
 
Liste der Anhänge anzeigen (Anzahl: 1)
Kann mir bitte jemand erklären wie genau die Speicherlecksuche mit FastMM4 funktioniert?

Ich habe in FastMM4Options.inc die Optionen EnableMemoryLeakReporting und FullDebugMode aktiviert.

Beispielcoder erzeugt der paar Bytes Speicher leaked. Am Ende der Ausführung bekomme ich die Meldung, dass Speicher geleakt wurde.
Details dazu stehen in der LogDatei.

Wenn ich jedoch die LogDatei anschaue finde ich (für mich persönlich) keinerlei nützliche Info die mir helfen würde den Ort des Speicherlecks zu finden.
Das Testprogramm zeigt die (zufällige) Adresse des Pointers der nicht freigegeben wird als $19FB70. In der LogDatei bekomme einen Stack Trace der mich gar nicht weiter bringt, und einen Speicherauszug von Adresse $7FE35550, die auf dem ersten Blick auch nichts mit dem Leck zu tun hat.

Hat jemand von euch vielleicht Tips um die Codezeile mit dem Leak zu finden?

Beispielcode inkl FastMM4 mit kompilierter Exe ist angehängt.
Delphi-Quellcode:
var
  Form1: TForm1;

const data = #255#255#255#255#255#255#255#255#255;

implementation

{$R *.dfm}

procedure TForm1.FormShow(Sender: TObject);
var p: PChar;
begin
  GetMem(p, SizeOf(Data)+1);
  p := data;
  Caption := '$'+IntToHex(Integer(Addr(p)), 1)+':'+p;
end;
Delphi-Quellcode:
--------------------------------2020/6/11 2:38:16--------------------------------
A memory block has been leaked. The size is: 12

This block was allocated by thread 0x76F0, and the stack trace (return addresses) at the time was:
402D38 
451AE4 
4496D3 
44C6A6 
432337 
77551031 [RtlCaptureStackBackTrace]
426C41 
742C9FCB [SE_GetProcAddressForCaller]
426C41 
742C9FE3 [SE_GetProcAddressForCaller]
742CA00D [SE_GetProcAddressForCaller]

The block is currently used for an object of class: Unknown

The allocation number is: 355

Current memory dump of 256 bytes starting at pointer address 7FE35550:
8C 7C 45 00 80 DC 9A 65 A5 80 80 80 80 80 80 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Œ  |  E . €  Ü  š  e ¥  €  €  €  €  €  €  €  . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

--------------------------------2020/6/11 2:38:16--------------------------------
This application has leaked memory. The small block leaks are (excluding expected leaks registered by pointer):

5 - 12 bytes: Unknown x 1

Note: Memory leak detail is logged to a text file in the same folder as this application. To disable this memory leak check, undefine "EnableMemoryLeakReporting".

hoika 11. Jun 2020 05:04

AW: Speicherleaks finden mit FastMM4
 
Hallo,
die externen Debug-Optionen einschalten (bei den Linker-Optionen zu finden)

jaenicke 11. Jun 2020 05:05

AW: Speicherleaks finden mit FastMM4
 
Du hast keine Debuginformationen einkompiliert (sieht man an DebugInfo=0 in der .dof Datei). Ohne bekommst du auch keinen Stacktrace.

In aktuelleren Delphiversionen ist FastMM übrigens schon in Delphi integriert.

TiGü 11. Jun 2020 09:08

AW: Speicherleaks finden mit FastMM4
 
Zitat:

Zitat von jaenicke (Beitrag 1467032)
In aktuelleren Delphiversionen ist FastMM übrigens schon in Delphi integriert.

Himi ist ja auch so ein Kandidat, der das immer wieder schreibt, aber ihr wisst es doch alle eigentlich besser. :warn:
Nur mit dem aufgebohrten FastMM per externer Unit+Inc und Debug-DLL bekommt man aussagekräftige Log-Dateien und Warnungen, wenn Speicher durch Überschreiben korrumpiert wird.
Das bisschen an Information das per MessageBox vom integrierten FastMM durch ReportMemoryLeaksOnShutdown := True; ggf. gezeigt wird, ist ja nur die Spitze des Eisberges und würde sogar in dem Beispielfall hier null weiterhelfen.

generic 11. Jun 2020 10:37

AW: Speicherleaks finden mit FastMM4
 
Kennst du mein Video?

Von 0 auf 100 - FastMM4 - Ein Speichermanager für Delphi
https://www.youtube.com/watch?v=o0yZgQoV8MA

Benmik 11. Jun 2020 15:07

AW: Speicherleaks finden mit FastMM4
 
Außerdem gibt es doch seit Kurzem FastMM5 ohne die Inc-Datei.

Shark99 11. Jun 2020 16:00

AW: Speicherleaks finden mit FastMM4
 
Es gibt auch eine AVX Version von FastMM4: https://github.com/maximmasiutin/FastMM4-AVX

Benmik 11. Jun 2020 16:09

AW: Speicherleaks finden mit FastMM4
 
Ja, aber die ist 2 Jahre alt (Mai 2018). FastMM5 ist von Grund auf neu geschrieben, wie da steht, da sollte FastMM4 obsolet sein.

Shark99 11. Jun 2020 18:31

AW: Speicherleaks finden mit FastMM4
 
MM5 geht imho erst ab XE3. FastMM4-AVX ist eine gute Alternative um alten Projekten einen Performance Boost zu geben.

Harry Stahl 12. Jun 2020 09:47

AW: Speicherleaks finden mit FastMM4
 
Zitat:

Zitat von generic (Beitrag 1467048)
Kennst du mein Video?

Von 0 auf 100 - FastMM4 - Ein Speichermanager für Delphi
https://www.youtube.com/watch?v=o0yZgQoV8MA

Das Video habe ich gesehen, war sehr hilfreich und ich habe es dann erfolgreich in der erweiterten Variante umsetzen können und so ein paar Memory-Leaks schließen können, die ich mit der einfachen Variante nicht ausfindig machen konnte.

Eine Frage in diesem Zusammenhang:

Die MemoryManager_EventLlog Datei war über 1 MB groß, häufiger mit doppelten Einträgen. Gibt es eigentlich ein Tool, welches die Einträge auswertet und dann die Unit öffnet und zur Zeile springt, wo der Speicherverbrauchende Prozess erzeugt wurde? Denn manuell das alles zu sichten, war schon sehr unkomfortabel...

Delphi.Narium 12. Jun 2020 10:01

AW: Speicherleaks finden mit FastMM4
 
Schau mal bitte dort: GitHub: jcl/jcl/experts/stacktraceviewer/APIExamples/FastMM/

Eventuell kannst Du damit was anfangen.

stahli 12. Jun 2020 10:11

AW: Speicherleaks finden mit FastMM4
 
Du kannst Dir evtl. mal EurekaLog anschauen.
Das war m.E. schon komfortabler.

Ist aber für mich eine Weile her und ich weiß nicht, ob es noch eine kostenfreie Emba-Edition gibt.

Harry Stahl 12. Jun 2020 10:24

AW: Speicherleaks finden mit FastMM4
 
Zitat:

Zitat von Delphi.Narium (Beitrag 1467132)
Schau mal bitte dort: GitHub: jcl/jcl/experts/stacktraceviewer/APIExamples/FastMM/

Eventuell kannst Du damit was anfangen.

Da braucht man wohl die JCL zu. JEDI-Komponenten verwende ich aber nicht (aus Gründen der "Komponentensparsamkeit")...

Aber evtl. gibt es die fertige Exe irgendwo als Download?

Delphi.Narium 12. Jun 2020 11:10

AW: Speicherleaks finden mit FastMM4
 
Und wenn Du Dir die Mühe machst, Dir das mal anzuschauen, wirst Du feststellen, dass das die JCL ist und diese (bekanntermaßen) keine Komponenten enthält und Du daher dafür auch keine Komponenten sparen musst.

Es handelt sich um einen Experten für die IDE. Den musst Du dann schon kompilieren und installieren.

Man könnte sich aber auch einfach mal die Quellen anschauen, um zu sehen, wie die das machen und dann eine eigene Lösung finden. Nur so als Idee ;-)

In meinem Log muss ich übrigens nur nach den Zeilen suchen, die mit einer in eckigen Klammern eingefassten Zahl enden.

Sieht z. B. so aus:
Code:
6A8ED2 [e:\Delphi\Indy10\Lib\Core\IdThreadSafe.pas][IdThreadSafe][TIdThreadSafe.Create][253]
Das kann man dann auch per eigenem Programm, Script, ... auswerten.

Hab' mir mal eben für meinen Editor ein PascalScript geschrieben:
Delphi-Quellcode:
program Test;
var
        i : Integer;
        sl : TStringList;
        s : String;
begin
  sl := TStringList.Create;
  sl.LoadFromFile('Programmname_MemoryManager_EventLog.txt');
  for i := sl.Count - 1 downto 0 do begin
    sl[i] := ReverseString(sl[i]);
    if Copy(sl[i],1,1) = ']' then begin
      s := Copy(sl[i],2,Length(sl[i]));
      s := Copy(s,1,Pos('[',s) - 1);
      if StrToIntDef(s,-1) <> -1 then sl[i] := ReverseString(sl[i]) else sl.Delete(i);
    end else sl.Delete(i);
  end;
  sl.Sort;
  for i := sl.Count - 1 downto 1 do if sl[i] = sl[i - 1] then sl.Delete(i);
  sl.SaveToFile('Programmname_MemoryManager_EventLog.txt.report');
  sl.Free;
end.
Damit hab' ich dann eine Datei, in der alle Zeilen stehen, die ich mir anschauen muss. Sieht so aus:
Code:
690647 [e:\Delphi\Indy10\Lib\System\IdStack.pas][IdStack][IdStack][1225]
69F22B [e:\Delphi\Indy10\Lib\Core\IdIOHandler.pas][IdIOHandler][TIdIOHandler.SetDefaultClass][910]
69F296 [e:\Delphi\Indy10\Lib\Core\IdIOHandler.pas][IdIOHandler][TIdIOHandler.RegisterIOHandler][953]
6A8EB6 [e:\Delphi\Indy10\Lib\Core\IdThreadSafe.pas][IdThreadSafe][TIdThreadSafe.Create][251]
6A8ED2 [e:\Delphi\Indy10\Lib\Core\IdThreadSafe.pas][IdThreadSafe][TIdThreadSafe.Create][253]
6A9079 [..\..\Indy10\Lib\Core\IdThread.pas][IdThread][IdThread][730]
War ungefähr 10 Minuten Aufwand ;-)

Datei analysieren, benötigte Informationen erkennen. Script schreiben, das diese raussucht und speichert.

Mit dem Ergebnis muss man dann auf die Suche gehen. Das kann dann schonmal was länger dauern :-(

PS:

in der FastMM4Options.inc hab' ich
Delphi-Quellcode:
{$define LogMemoryLeakDetailToFile}
{$define EnableMemoryLeakReportingUsesQualifiedClassName}
{$define ClearLogFileOnStartup}
aktiviert.

Musst halt mal schauen, was da für Dich die sinnvollste Ausgabe ist.

Harry Stahl 12. Jun 2020 11:40

AW: Speicherleaks finden mit FastMM4
 
@Delphi.Narium

Zu JCL/Jedi: Neben Komponentensparsamkeit gilt für mich auch eine Expertensparsamkeit, außer GExperts verwende ich da nichts (jedenfalls in den aktuellen Delphi-Versionen, in älteren Delphi-Versionen notgedrungen auch CNPack). Sonst nur externe Experten (z.B. Pascal-Analyser).

Zu Deinem Excerpt: Ja prima, damit komme ich zurecht.

Shark99 12. Jun 2020 13:50

AW: Speicherleaks finden mit FastMM4
 
hier der Log mit TD32 Debuginfo:
Delphi-Quellcode:
--------------------------------2020/6/12 14:48:24--------------------------------
A memory block has been leaked. The size is: 12

This block was allocated by thread 0x5D2C, and the stack trace (return addresses) at the time was:
402D38 [System][@GetMem]
451AE4 [Unit1.pas][Unit1][TForm1.FormShow][30]
4496D3 [Forms][TCustomForm.DoShow]
44C6A6 [Forms][TCustomForm.CMShowingChanged]
432337 [Controls][TControl.WndProc]
77181031 [RtlCaptureStackBackTrace]
426C41 [MultiMon][InitAnApi]
73B99FCB [SE_GetProcAddressForCaller]
426C41 [MultiMon][InitAnApi]
73B99FE3 [SE_GetProcAddressForCaller]
73B9A00D [SE_GetProcAddressForCaller]

The block is currently used for an object of class: Unknown

The allocation number is: 355

Current memory dump of 256 bytes starting at pointer address 7FE35550:
8C 7C 45 00 80 64 CE CE A6 80 80 80 80 80 80 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Œ  |  E . €  d Π Π ¦  €  €  €  €  €  €  €  . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

--------------------------------2020/6/12 14:48:24--------------------------------
This application has leaked memory. The small block leaks are (excluding expected leaks registered by pointer):

5 - 12 bytes: Unknown x 1

Note: Memory leak detail is logged to a text file in the same folder as this application. To disable this memory leak check, undefine "EnableMemoryLeakReporting".
Der Stacktrace ist jetzt sehr hilfreich. Den Mem Dump verstehe ich aber immer noch nicht. Wie kommt er drauf die Adresse 7FE35550 für den Mem Dump anzuzeigen?

Harry Stahl 12. Jun 2020 15:45

AW: Speicherleaks finden mit FastMM4
 
Liste der Anhänge anzeigen (Anzahl: 1)
Na, wenn das so einfach ist, werde ich das noch in meinen Pascal Editor einbauen.:-D

Wenn ein Projekt geladen ist, nur rechts in dem Projektfenster auf das Memory-Symbol klicken. Wenn die EventLog-Datei im Standardverzeichnis liegt, wird sie automatisch geladen, wenn nicht, erhält man eine Aufforderung, den Pfad anzugeben.

Dann wird auf der linken Seite automatisch ein neuer Tab "Leaks" amgezeigt, wo nach Units unterteilt die entsprechenden Prozeduren und Zeilenangaben stehen. Per Doppelklick auf einen Eintrag wird die entsprechende Unit geöffnet (in der Vollversion - in der Testversion muss man es selber machen) und der Cursor in die entsprechende Zeile gestellt.

Siehe anliegenden Screenshot.

Ich wollte heute Abend sowieso eine aktualisierte Version hochladen (muss noch einen kleinen Bug entfernen, wie man sieht werden ein paar Einträge in der Liste noch doppelt angezeigt), da wird das dann auch drin sein. Das ist jetzt echt sehr komfortabel...

Harry Stahl 12. Jun 2020 19:10

AW: Speicherleaks finden mit FastMM4
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich habe das jetzt mal ein wenig lesbarer gestaltet, siehe anliegenden Screenshot im Vergleich zum vorherigen post.

Ferner habe ich in der Hilfe noch mal eine Beschreibung aufgenommen, wie man den fastMM4 in das Projekt integriert und was man sonst noch so einstellen muss.

In der Hilfe verweise ich zudem auf Bernds video (siehe oben) und auf den Source bei Github.

Die aktualisierte Version 3.37 vom Pascal Project Manager & Editor (die nun auch Delphi 10.4 unterstützt) habe ich gerade hochgeladen:

https://hastasoft.de/PPME.htm

generic 16. Jun 2020 08:29

AW: Speicherleaks finden mit FastMM4
 
Zitat:

Zitat von Benmik (Beitrag 1467071)
Außerdem gibt es doch seit Kurzem FastMM5 ohne die Inc-Datei.

Schade, Version 5 steht unter GPL Lizenz - dadurch in kostenfreien aber closed Source-Projekten nicht einsetzbar ohne die 100 Taler zu berappen.

Stevie 16. Jun 2020 09:01

AW: Speicherleaks finden mit FastMM4
 
Zitat:

Zitat von generic (Beitrag 1467388)
Schade, Version 5 steht unter GPL Lizenz - dadurch in kostenfreien aber closed Source-Projekten nicht einsetzbar ohne die 100 Taler zu berappen.

Wie viele kostenlose aber closed Source-Projekte gibt es denn, die heftigst multithreading betreiben, für dass sie FastMM5 benötigen?

freimatz 17. Jun 2020 13:13

AW: Speicherleaks finden mit FastMM4
 
Zitat:

Zitat von Harry Stahl (Beitrag 1467131)
Gibt es eigentlich ein Tool, welches die Einträge auswertet und dann die Unit öffnet und zur Zeile springt, wo der Speicherverbrauchende Prozess erzeugt wurde? Denn manuell das alles zu sichten, war schon sehr unkomfortabel...

madExcept


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:11 Uhr.

Powered by vBulletin® Copyright ©2000 - 2022, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf