Есть ли способ программно определить, не освобожден ли конкретный блок памяти FastMM?

103

Я пытаюсь определить, не был ли освобожден блок памяти. Конечно, менеджер сообщает мне это с помощью диалогового окна или файла журнала, но что, если я хочу сохранить результаты в базе данных? Например, я хотел бы иметь в таблице базы данных имена подпрограмм, которые выделяли данные блоки.

После прочтения документации FastMM я знаю, что с версии 4.98 у нас есть возможность получать уведомления от менеджера о выделении, освобождении и перераспределении памяти по мере их возникновения. Например, OnDebugFreeMemFinishнам передается событие, PFullDebugBlockHeaderкоторое содержит полезную информацию. Не PFullDebugBlockHeaderхватает одного - информации о том, был ли данный блок освобожден приложением.

Разве OnDebugFreeMemFinishвызывается только для не освобожденных блоков? Этого я не знаю и хотел бы узнать.

Проблема в том, что даже подключившись к OnDebugFreeMemFinishсобытию, я не смог узнать, освобожден блок или нет.

Вот пример:

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.

Мне не хватает обратного вызова, например:

procedure OnMemoryLeak(APointer: PFullDebugBlockHeader);

После просмотра исходного кода FastMM я увидел, что есть процедура:

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

что можно было бы переопределить, но, может быть, есть более простой способ?

Wodzu
источник
7
Я всегда понимал, что FastMM может выполнять эту проверку только как ОЧЕНЬ ПОСЛЕДНЕЕ действие, которое программа должна выполнить по определению, поэтому к тому времени, когда FastMM сделает свой отчет, ваш код будет завершен. Чтобы получить частичное решение, вы всегда можете заглянуть в их источник, чтобы увидеть, как помечается выделенная память.
Брайан Фрост,
6
Сообщили, как ожидалось утечка? Вы зарегистрировали это как положено. Кроме того, вы не можете решить, что память утекает до выключения, если вы не предоставите сложную логику, которая понимает ожидаемое время жизни.
Дэвид Хеффернан,
6
Если OnDebugFreeMemFinishвызывается, это означает, что блок освобожден. Нет OnMemoryLeakсобытия. Такого события не могло быть никогда. FastMM при завершении работы определяет, что все блоки, которые не были освобождены, должны быть утечками. Он не может обнаружить утечку раньше этого.
Дэвид Хеффернан
12
Когда FastMM сообщает мне об утечке памяти, я отключаю инструменты и немедленно исправляю ее. Если вы этого не сделаете, вам будет сложно воспроизвести утечку. Если вы действительно хотите войти в базу данных, вам нужно взглянуть на функцию CheckBlocksOnShutdown. Еще одна потенциальная точка расширения - AppendEventLogя подозреваю, что вам нужно изменить источник FastMM.
Дэвид Хеффернан
12
Эмм, просто возьмите файл, проанализируйте его и поместите в БД?
Тони Хопкинсон

Ответы:

2

Даже если такой обработчик существует, он был бы почти бесполезен, так как все, включая БД, было бы отключено в то время, когда FastMM сообщает об утечках.

Итак, я предлагаю вам включить LogErrorsToFileвместе с FullDebugModeусловными операторами в FastMM4Options.inc. Это даст вам текстовый файл с утечками, который позже вы сможете проанализировать и поместить в БД.

Сергей Хейлик
источник