¿Hay alguna manera de saber mediante programación si FastMM no liberó un bloque de memoria en particular?

103

Estoy tratando de detectar si no se liberó un bloque de memoria. Por supuesto, el administrador me lo dice mediante un cuadro de diálogo o un archivo de registro, pero ¿y si quisiera almacenar los resultados en una base de datos? Por ejemplo, me gustaría tener en una tabla de base de datos los nombres de las rutinas que asignaron bloques determinados.

Después de leer una documentación de FastMM, sé ​​que desde la versión 4.98 tenemos la posibilidad de ser notificados por el administrador sobre las asignaciones de memoria, liberaciones y reasignaciones a medida que ocurren. Por ejemplo, un OnDebugFreeMemFinishevento nos está pasando un PFullDebugBlockHeaderque contiene información útil. Hay una cosa que PFullDebugBlockHeaderfalta: la información si el bloque dado fue liberado por la aplicación.

¿A menos que OnDebugFreeMemFinishse llame solo para bloques no liberados? Esto es lo que no sé y me gustaría averiguar.

El problema es que incluso al conectarme al OnDebugFreeMemFinishevento no pude averiguar si el bloque se liberó o no.

Aquí hay un ejemplo:

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.

Lo que me falta es la devolución de llamada como:

procedure OnMemoryLeak(APointer: PFullDebugBlockHeader);

Después de navegar por la fuente de FastMM, vi que hay un procedimiento:

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

que podría anularse, pero tal vez haya una manera más fácil.

Wodzu
fuente
7
Siempre he entendido que FastMM solo puede hacer esta verificación como la ÚLTIMA acción que el programa debe realizar, por definición, por lo que para cuando FastMM hace su informe, su código ha terminado. Para obtener una solución parcial, siempre puede echar un vistazo a su fuente para ver cómo se marca la memoria asignada.
Brian Frost
6
¿Reportado como fuga esperada? ¿Lo registró como se esperaba? Además, no puede decidir que la memoria se filtre hasta que se apague, a menos que proporcione una lógica compleja que comprenda la vida útil esperada.
David Heffernan
6
Si OnDebugFreeMemFinishse llama, significa que se liberó el bloque. No hay OnMemoryLeakevento. Nunca podría haber tal evento. Lo que FastMM hace es, cuando se apaga, determinar que cualquier bloque que no se haya liberado debe ser una fuga. No puede detectar una fuga antes de eso.
David Heffernan
12
Siempre que FastMM me dice que hay una pérdida de memoria, apago las herramientas y lo soluciono de inmediato. Si no lo hace, le resultará difícil reproducir la fuga. Si realmente desea iniciar sesión en la base de datos, deberá consultar la función CheckBlocksOnShutdown. Otro punto de extensión potencial es, AppendEventLogpero sospecho que necesitará modificar la fuente FastMM.
David Heffernan
12
Erm, ¿solo toma el archivo, lo analiza y lo pone en la base de datos?
Tony Hopkinson

Respuestas:

2

Incluso si existiera tal controlador, sería casi inútil, ya que todo, incluida la base de datos, se cerraría en el momento en que FastMM informa de las fugas.

Por lo tanto, le sugiero que active LogErrorsToFilejunto con los FullDebugModecondicionales FastMM4Options.inc. Esto le dará un archivo de texto con fugas, que luego puede analizar y poner en la base de datos.

Serhii Kheilyk
fuente