Existe-t-il un moyen de savoir par programme si un bloc de mémoire particulier n'a pas été libéré par FastMM?

103

J'essaye de détecter si un bloc de mémoire n'a pas été libéré. Bien sûr, le gestionnaire me dit cela par boîte de dialogue ou fichier journal, mais que faire si je souhaite stocker les résultats dans une base de données? Par exemple, je voudrais avoir dans une table de base de données des noms de routines qui allouent des blocs donnés.

Après avoir lu une documentation de FastMM, je sais que depuis la version 4.98, nous avons la possibilité d'être averti par le gestionnaire des allocations de mémoire, des libérations et des réallocations au fur et à mesure qu'elles se produisent. Par exemple, l' OnDebugFreeMemFinishévénement nous transmet un PFullDebugBlockHeaderqui contient des informations utiles. Il PFullDebugBlockHeadermanque une chose : les informations si le bloc donné a été libéré par l'application.

À moins que ne OnDebugFreeMemFinishsoit appelé uniquement pour les blocs non libérés? C'est ce que je ne sais pas et que j'aimerais découvrir.

Le problème est que même en OnDebugFreeMemFinishme connectant à un événement, je n'ai pas pu savoir si le bloc était libéré ou non.

Voici un exemple:

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.

Ce qui me manque, c'est le rappel comme:

procedure OnMemoryLeak(APointer: PFullDebugBlockHeader);

Après avoir parcouru la source de FastMM, j'ai vu qu'il y avait une procédure:

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

qui pourrait être annulé, mais peut-être existe-t-il un moyen plus simple?

Wodzu
la source
7
J'ai toujours compris que FastMM ne peut effectuer cette vérification que comme la TRÈS DERNIÈRE action que le programme devrait faire - par définition - donc au moment où FastMM fait son rapport, votre code est terminé. Pour obtenir une solution partielle, vous pouvez toujours consulter leur source pour voir comment la mémoire allouée est marquée.
Brian Frost
6
Signalé comme fuite attendue? L'avez-vous enregistré comme prévu. De plus, vous ne pouvez pas décider que la mémoire est perdue jusqu'à l'arrêt, sauf si vous fournissez une logique complexe qui comprend les durées de vie attendues.
David Heffernan le
6
Si OnDebugFreeMemFinishest appelé, cela signifie que le bloc a été libéré. Il n'y a pas d' OnMemoryLeakévénement. Il ne pourrait jamais y avoir un tel événement. Lors de l'arrêt, FastMM détermine que tous les blocs qui n'ont pas été libérés doivent être des fuites. Il ne peut pas détecter une fuite avant cela.
David Heffernan
12
Chaque fois que FastMM me dit qu'il y a une fuite de mémoire, je descends des outils et je le répare immédiatement. Si vous ne le faites pas, vous aurez du mal à reproduire la fuite. Si vous souhaitez vraiment vous connecter à la base de données, vous devrez regarder la fonction CheckBlocksOnShutdown. Un autre point d'extension potentiel est, AppendEventLogmais vous devrez modifier la source FastMM que je soupçonne.
David Heffernan
12
Euh, prends le fichier, analyse-le et place-le dans la base de données?
Tony Hopkinson

Réponses:

2

Même si un tel gestionnaire existait, il serait presque inutile, car tout, y compris la base de données, serait arrêté au moment où FastMM signale des fuites.

Donc, je vous suggère d'activer LogErrorsToFileavec les FullDebugModeconditions FastMM4Options.inc. Cela vous donnera un fichier texte avec des fuites, que vous pourrez ensuite analyser et mettre dans DB.

Serhii Kheilyk
la source