Existe uma maneira de saber programaticamente se determinado bloco de memória não foi liberado pelo FastMM?

103

Estou tentando detectar se um bloco de memória não foi liberado. Claro, o gerente me diz isso por caixa de diálogo ou arquivo de log, mas e se eu quiser armazenar os resultados em um banco de dados? Por exemplo, eu gostaria de ter em uma tabela de banco de dados os nomes das rotinas que alocaram determinados blocos.

Depois de ler a documentação do FastMM sei que desde a versão 4.98 temos a possibilidade de sermos notificados pelo gerente sobre as alocações, liberações e realocações de memória à medida que ocorrem. Por exemplo, o OnDebugFreeMemFinishevento está passando para nós um PFullDebugBlockHeaderque contém informações úteis. Há uma coisa que PFullDebugBlockHeaderestá faltando - a informação se o bloco fornecido foi liberado pelo aplicativo.

A menos que OnDebugFreeMemFinishseja chamado apenas para blocos não liberados? Isso eu não sei e gostaria de saber.

O problema é que, mesmo ao OnDebugFreeMemFinishme conectar ao evento, não consegui descobrir se o bloco foi liberado ou não.

Aqui está um exemplo:

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.

O que estou perdendo é o retorno de chamada como:

procedure OnMemoryLeak(APointer: PFullDebugBlockHeader);

Depois de navegar na fonte do FastMM, vi que existe um procedimento:

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

que poderia ser anulado, mas talvez haja uma maneira mais fácil?

Wodzu
fonte
7
Sempre entendi que FastMM só pode fazer essa verificação como a MUITO ÚLTIMA ação que o programa deve fazer - por definição - então, quando FastMM fizer seu relatório, seu código terá terminado. Para obter uma solução parcial, você sempre pode dar uma olhada na fonte para ver como a memória alocada está sinalizada.
Brian Frost
6
Relatado como vazamento esperado? Você registrou como esperado. Além disso, você não pode decidir que a memória está vazando até o desligamento, a menos que forneça uma lógica complexa que entenda a expectativa de vida.
David Heffernan
6
Se OnDebugFreeMemFinishfor chamado, significa que o bloco foi liberado. Não há OnMemoryLeakevento. Nunca poderia haver tal evento. O que o FastMM faz é, ao desligar, determinar que todos os blocos que não foram liberados devem apresentar vazamentos. Ele não pode detectar um vazamento antes disso.
David Heffernan
12
Sempre que FastMM me diz que há um vazamento de memória, eu inativo as ferramentas e conserto imediatamente. Se você não fizer isso, será difícil reproduzir o vazamento. Se você realmente deseja fazer logon no banco de dados, será necessário examinar a função CheckBlocksOnShutdown. Outro ponto de extensão potencial é, AppendEventLogmas você precisará modificar a fonte FastMM que eu suspeito.
David Heffernan
12
Erm apenas pegar o arquivo, analisá-lo e colocá-lo no banco de dados?
Tony Hopkinson

Respostas:

2

Mesmo se tal manipulador existir, ele seria quase inútil, pois tudo, incluindo o banco de dados, seria encerrado no momento em que o FastMM relatasse os vazamentos.

Portanto, sugiro que você ative LogErrorsToFilejunto com as FullDebugModecondicionais em FastMM4Options.inc. Isso lhe dará um arquivo de texto com vazamentos, que mais tarde você pode analisar e colocar no banco de dados.

Serhii Kheilyk
fonte