Czy istnieje sposób, aby programowo stwierdzić, czy dany blok pamięci nie został zwolniony przez FastMM?

103

Próbuję wykryć, czy blok pamięci nie został zwolniony. Oczywiście menedżer mówi mi o tym w oknie dialogowym lub pliku dziennika, ale co jeśli chciałbym przechowywać wyniki w bazie danych? Na przykład chciałbym mieć w tabeli bazy danych nazwy procedur, które przydzieliły dane bloki.

Po przeczytaniu dokumentacji FastMM wiem, że od wersji 4.98 mamy możliwość powiadamiania menedżera o alokacjach, zwolnieniach i realokacjach pamięci w momencie ich wystąpienia. Na przykład OnDebugFreeMemFinishprzekazuje nam zdarzenie, PFullDebugBlockHeaderktóre zawiera przydatne informacje. Brakuje tylko jednego PFullDebugBlockHeader- informacji czy dany blok został zwolniony przez aplikację.

Chyba że OnDebugFreeMemFinishjest wezwany tylko do niezwolnionych bloków? Tego nie wiem i chciałbym się dowiedzieć.

Problem polega na tym, że nawet podłączając się do OnDebugFreeMemFinishzdarzenia nie byłem w stanie dowiedzieć się, czy blok został zwolniony, czy nie.

Oto przykład:

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.

Brakuje mi oddzwonienia takiego jak:

procedure OnMemoryLeak(APointer: PFullDebugBlockHeader);

Po przejrzeniu źródła FastMM zobaczyłem, że istnieje procedura:

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

które można by przesłonić, ale może istnieje prostszy sposób?

Wodzu
źródło
7
Zawsze rozumiałem, że FastMM może dokonać tego sprawdzenia tylko jako BARDZO OSTATNEGO działania, które program powinien wykonać - z definicji - więc zanim FastMM dokona raportu, kod zostanie zakończony. Aby uzyskać częściowe rozwiązanie, zawsze możesz zajrzeć do ich źródła, aby zobaczyć, jak oznaczona jest przydzielona pamięć.
Brian Frost,
6
Zgłoszono zgodnie z oczekiwaniami wyciek? Czy zarejestrowałeś to zgodnie z oczekiwaniami. Nie możesz również zdecydować, że pamięć wycieknie do zamknięcia, chyba że zapewnisz złożoną logikę, która rozumie oczekiwane okresy życia.
David Heffernan,
6
Jeśli OnDebugFreeMemFinishzostanie wywołane, oznacza to, że blok został zwolniony. Nie ma żadnego OnMemoryLeakwydarzenia. Nigdy nie mogło być takiego wydarzenia. To, co robi FastMM, polega na ustaleniu podczas zamykania, że ​​wszelkie bloki, które nie zostały uwolnione, muszą być przeciekami. Nie może wykryć wycieku wcześniej.
David Heffernan,
12
Zawsze, gdy FastMM mówi mi, że nastąpił wyciek pamięci, wyłączam narzędzia i natychmiast go naprawiam. Jeśli tego nie zrobisz, trudno będzie odtworzyć wyciek. Jeśli naprawdę chcesz zalogować się do bazy danych, musisz spojrzeć na funkcję CheckBlocksOnShutdown. Innym potencjalnym punktem rozszerzenia jest, AppendEventLogale podejrzewam, że będziesz musiał zmodyfikować źródło FastMM.
David Heffernan,
12
Po prostu weź plik, przeanalizuj go i umieść w bazie danych?
Tony Hopkinson

Odpowiedzi:

2

Nawet gdyby taki program obsługi istniał, byłby prawie bezużyteczny, ponieważ wszystko, łącznie z bazą danych, zostałoby wyłączone w momencie, gdy FastMM zgłasza wycieki.

Sugeruję więc włączenie LogErrorsToFilewraz z FullDebugModewarunkami warunkowymi FastMM4Options.inc. W ten sposób otrzymasz plik tekstowy z przeciekami, który później możesz przeanalizować i umieścić w DB.

Serhii Kheilyk
źródło