C'è un modo per sapere a livello di programmazione se un particolare blocco di memoria non è stato liberato da FastMM?


103

Sto cercando di rilevare se un blocco di memoria non è stato liberato. Ovviamente, il manager me lo dice tramite la finestra di dialogo o il file di registro, ma cosa succede se volessi memorizzare i risultati in un database? Ad esempio, vorrei avere in una tabella di database i nomi delle routine che allocano determinati blocchi.

Dopo aver letto una documentazione di FastMM, so che dalla versione 4.98 abbiamo la possibilità di essere avvisati dal manager sulle allocazioni di memoria, sui liberi e sulle riallocazioni quando si verificano. Ad esempio ci OnDebugFreeMemFinishsta passando un evento PFullDebugBlockHeaderche contiene informazioni utili. C'è una cosa che PFullDebugBlockHeadermanca: le informazioni se il blocco specificato è stato liberato dall'applicazione.

A meno che non OnDebugFreeMemFinishvenga chiamato solo per blocchi non liberati? Questo è quello che non so e vorrei scoprire.

Il problema è che anche agganciando OnDebugFreeMemFinishall'evento non sono riuscito a scoprire se il blocco è stato liberato o meno.

Ecco un esempio:

program MemLeakTest;

{$APPTYPE CONSOLE}

uses
  FastMM4, ExceptionLog, SysUtils;


procedure MemFreeEvent(APHeaderFreedBlock: PFullDebugBlockHeader; AResult: Integer);
begin
//This is executed at the end, but how should I know that this block should be freed
//by application? Unless this is executed ONLY for not freed blocks.
end;

procedure Leak;
var
  MyObject: TObject;
begin
  MyObject := TObject.Create;
end;

begin
  OnDebugFreeMemFinish := MemFreeEvent;
  Leak;
end.

Quello che mi manca è il callback come:

procedure OnMemoryLeak(APointer: PFullDebugBlockHeader);

Dopo aver sfogliato i sorgenti di FastMM ho visto che esiste una procedura:

procedure LogMemoryLeakOrAllocatedBlock(APointer: PFullDebugBlockHeader; IsALeak: Boolean);

quale potrebbe essere sovrascritto, ma forse c'è un modo più semplice?


7
Ho sempre capito che FastMM può fare questo controllo solo come l'ULTIMA azione che il programma dovrebbe compiere - per definizione - quindi nel momento in cui FastMM fa il suo rapporto il tuo codice è terminato. Per ottenere una soluzione parziale puoi sempre dare un'occhiata alla loro fonte per vedere come viene contrassegnata la memoria allocata.
Brian Frost

6
Segnalato come perdita prevista? L'hai registrato come previsto. Inoltre, non è possibile decidere che la memoria venga persa fino all'arresto, a meno che non si fornisca una logica complessa che comprenda la durata prevista.
David Heffernan

6
Se OnDebugFreeMemFinishviene chiamato significa che il blocco è stato liberato. Non ci sono OnMemoryLeakeventi. Non potrebbe mai esserci un simile evento. Quello che fa FastMM è, all'arresto, determinare che tutti i blocchi che non sono stati liberati devono essere perdite. Non è in grado di rilevare una perdita prima di allora.
David Heffernan

12
Ogni volta che FastMM mi dice che c'è una perdita di memoria, metto giù gli strumenti e lo aggiusto immediatamente. Se non lo fai, troverai difficile riprodurre la perdita. Se desideri davvero accedere al database, dovrai esaminare la funzione CheckBlocksOnShutdown. Un altro potenziale punto di estensione è AppendEventLogma è necessario modificare la fonte FastMM che sospetto.
David Heffernan

12
Ehm solo prendere il file, analizzarlo e metterlo nel DB?
Tony Hopkinson,

Risposte:


2

Anche se tale gestore esistesse, sarebbe quasi inutile, poiché tutto, incluso il DB, verrebbe chiuso nel momento in cui FastMM segnala le perdite.

Quindi, ti suggerisco di attivare LogErrorsToFileinsieme ai FullDebugModecondizionali in FastMM4Options.inc. Questo ti darà un file di testo con perdite, che in seguito potrai analizzare e inserire nel DB.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.