![]() |
FastMM4 detected that a block has been modified after being freed
Guten Abend,
ich verstehe diese Ausgabe von FastMM4 nicht. Was gibt es denn dagegen einzuwenden, wenn ein vorher freigegebener Speicher wieder benutzt wird? Ich habe eine Applikation die Tracedateien einließt. Öffne ich eine Datei einmal und zeige die Daten an danach schließe ich das Programm wieder. FastMM4 zeigt keine Leaks o.ä. an. Öffne ich eine Datei einmal, zeige die Daten an. Schließe diese Datei und öffne die gleiche Datei erneut wirft mir FastMM4 diese Meldung um die Ohren. Wenn ich die Tracedatei schließe gebe ich Thread TDecoder frei. Wenn ich die Tracedatei erneut öffne wird der Thread wieder neu erstellt. Was soll mir das TThreadLocalCounter.Recycle sagen? Hat da jemand Erfahrung mit? Grüße Klaus FastMM has detected an error during a free block scan operation. FastMM detected that a block has been modified after being freed. Modified byte offsets (and lengths): 13(1) The previous block size was: 76 This block was previously allocated by thread 0xCA4, and the stack trace (return addresses) at the time was: 402EEA [system.pas][System][@GetMem][2648] 403C67 [system.pas][System][TObject.NewInstance][8824] 403FEE [system.pas][System][@ClassCreate][9489] 4AEC96 [decodeTrace.pas][decodeTrace][TDecodeTrace.create] 403CA5 [system.pas][System][TObject.Create][8840] 4AF64C [showTraceForm.pas][showTraceForm][TshowTraces.FormCreate][124] 41444F [sysutils.pas][SysUtils][TThreadLocalCounter.Recycle][16610] 46CE4F [Forms.pas][Forms][TCustomForm.DoCreate][2756] 46CA97 [Forms.pas][Forms][TCustomForm.AfterConstruction][2680] 40405C [system.pas][System][@AfterConstruction][9537] 46CA63 [Forms.pas][Forms][TCustomForm.Create][2676] The block was previously used for an object of class: TDecodeTrace The allocation number was: 207867 The block was previously freed by thread 0x168, and the stack trace (return addresses) at the time was: 402F06 [system.pas][System][@FreeMem][2693] 403C85 [system.pas][System][TObject.FreeInstance][8830] 404039 [system.pas][System][@ClassDestroy][9530] 4AED2E [decodeTrace.pas][decodeTrace][TDecodeTrace.Destroy][45] 403CCB [system.pas][System][TObject.Free][8849] 423AE0 [classes.pas][Classes][ThreadProc][9876] 404B36 [system.pas][System][ThreadWrapper][12127] 7C80B729 [Unknown function at GetModuleFileNameA] The current thread ID is 0xCA4, and the stack trace (return addresses) leading to this error is: 40B6D8 [FastMM4.pas][FastMM4][CheckBlocksOnShutdown][7981] 40C45E [FastMM4.pas][FastMM4][FinalizeMemoryManager][9045] 40C4A6 [FastMM4.pas][FastMM4][Finalization][9126] 4047BB [system.pas][System][FinalizeUnits][11273] 404A53 [system.pas][System][@Halt0][11943] 4B1996 7C90DCBA [ZwSetInformationThread] 7C817077 [Unknown function at RegisterWaitForInputIdle] Current memory dump of 256 bytes starting at pointer address 7FF851C0: [Dump entfernt] |
AW: FastMM4 detected that a block has been modified after being freed
Dein Code hat einen Speicherblock (=ein Objekt) verändert, nachdem es freigegeben wurde.
Also im Prinzip soetwas:
Delphi-Quellcode:
Es könnte aber auch ein falsch programmierter Destruktor dahinterstecken:
var
x : TMyClass; begin x := TMyClass.Create; x.MyProperty := 42; x.Free; // und jetzt kommt's x.MyProperty := 66; end
Delphi-Quellcode:
destructor TMyClass.Destroy;
begin inherited; // Problem: nach Aufruf von inherited ist der Speicher freigegeben // daher ist es verboten, jetzt noch damit zu arbeiten FTimerInterval := 0; end; |
AW: FastMM4 detected that a block has been modified after being freed
Zitat:
Delphi-Quellcode:
//Unit1.pas.55: end;
cmp byte ptr [ebp-$05],$00 jle +$08 // nur im äußersten "Destroy" ClassDestroy aufrufen mov eax,[ebp-$04] call @ClassDestroy pop ecx pop ecx pop ebp ret |
AW: FastMM4 detected that a block has been modified after being freed
Gute Morgen,
.. mhm irgendwie komme ich nicht so recht weiter.
Delphi-Quellcode:
procedure TshowTraces.FormCreate(Sender: TObject);
var headerLine : TStringList; mStream : TMemoryStream; begin errorLog := TLogger.getInstance; traceMessageList := TTraceMessageList.getInstance; caption := 'show trace '+extractFileName(traceFileName); mStream := TMemoryStream.Create; decoder := TDecodeTrace.create; try mStream.LoadFromFile(traceFileName); decoder.addTrace(mStream); finally freeAndNil(mStream); end; end;
Delphi-Quellcode:
procedure TshowTraces.FormClose(Sender: TObject; var Action: TCloseAction);
begin output.Enabled := false; if assigned(decoder) then decoder.terminate; freeAndNil(traceMessageList); end;
Delphi-Quellcode:
constructor TDecodeTrace.create;
begin inherited create(true); freeOnTerminate := true; mStream := TMemoryStream.Create; errorLog := TLogger.getInstance; protMessages := TProtMessages.getInstance; end;
Delphi-Quellcode:
procedure TDecodeTrace.addTrace(traceStream: TMemoryStream);
var streamPosition : Int64; begin if not suspended then suspend; streamPosition := mStream.Position; mStream.Seek(0,soFromEnd); traceStream.saveToStream(mStream); mStream.Seek(streamPosition,soFromBeginning); resume; end;
Delphi-Quellcode:
Ich sehe hier nicht unbedingt das etwas falsch freigegeben oder auch unerlaubt wieder benutzt wird.
destructor TDecodeTrace.Destroy;
begin if assigned(mstream) then freeAndNil(mStream); sleep(200); inherited destroy; freeAndNil(protMessages); end; Grüße Klaus |
AW: FastMM4 detected that a block has been modified after being freed
Du verwendest in der Klasse TDecodeTrace zwei Objekte, die du besser übergeben solltest:
Delphi-Quellcode:
Dabei sind FStream, FerrorLog und FprotMessage lokale Felder der Klasse.
constructor TDecodeTrace.create(logger:TLogger; pm:TProtMessages);
begin inherited create(true); freeOnTerminate := true; FStream := TMemoryStream.Create; FerrorLog := logger; FprotMessages := pm; end; Der Destruktor sieht dann so aus:
Delphi-Quellcode:
Da der Logger und ProtMessage über den Konstruktor übergeben wurden, braucht man die Objekte im Destruktor auch nicht freigeben.
destructor TDecodeTrace.Destroy;
begin FStream.Free; sleep(200); // wozu? inherited destroy; end; Das liegt dann in der Verantwortung des Aufrufers. |
AW: FastMM4 detected that a block has been modified after being freed
Man muss die Meldung genau lesen.
Zitat:
FastMM überschreibt beim Destroy den von Objekt benutzten Speicher mit Daten, versieht ihn sozusagen mit einem Fingerabdruck. beim Aufruf von "CheckBlocksOnShutdown" wird geprüft, ob der Fingerabdruck noch stimmt. WO und WER das war, steht da nicht. Nur DAS es passiert ist. Naheliegend ist der Fall, den sx2008 erklärt hat Zitat:
Auch ein nicht abgefangener RangeCheck (Zugriff über Array-Grenzen hinweg) kann u.A. die Ursache sein (Schalte mal RangeCheck ein). Da es sich beim Objekt um ein Singleton handelt, könntest Du dir einfach den Speicherbereich anzeigen lassen und schauen, in welchem Schritt das Überschreiben passiert. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:37 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz