How to configure FastMM to detect memory leak in a dll

delphi, delphi-xe3, dll, fastmm

Solution

The reason that your DLL is not reporting leaks stems from this code in the FastMM shutdown:

  CheckBlocksOnShutdown(
  {$ifdef EnableMemoryLeakReporting}
        True
    {$ifdef RequireIDEPresenceForLeakReporting}
        and DelphiIsRunning
    {$endif}
    {$ifdef RequireDebuggerPresenceForLeakReporting}
        and ((DebugHook <> 0)
        {$ifdef PatchBCBTerminate}
        or (Assigned(pCppDebugHook) and (pCppDebugHook^ <> 0))
        {$endif PatchBCBTerminate}
        )
    {$endif}
    {$ifdef ManualLeakReportingControl}
        and ReportMemoryLeaksOnShutdown
    {$endif}
  {$else}
        False
  {$endif}
  );

In your options, `RequireDebuggerPresenceForLeakReporting` is defined. What's more, in the DLL, `DebugHook` is equal to `0`, presumably because you are debugging the application rather than the DLL. This means that you call `CheckBlocksOnShutdown` passing `False`. And that `False` disables reporting of leaks.

You can resolve this by undefining `RequireDebuggerPresenceForLeakReporting`.

Problem

I can't figure out how to detect memory leaks in a statically or even dynamically linked dll. I just want to detect the leaks in the dll, and I don't want to share the memory manager between the dll, and the app. Additionally the dll is linked with runtime packages My sample dll looks like this: ``` library dll; uses fastmm4, System.SysUtils, System.Classes; {$R *.res} procedure MyInit; stdcall; Begin TObject.Create; End; exports MyInit; begin end. ``` application dpr: ``` program app; uses //fastmm4, Vcl.Forms, main in 'main.pas' {Form1}; {$R *.res} begin Application.Initialize; Application.MainFormOnTaskbar := True; Application.CreateForm(TForm1, Form1); Application.Run; end. ``` Note: If I uncomment fastmm4, than I can detect the memleak caused by the application (TStringList.Create), but not the leak in the dll. And in the application main unit: ``` unit main; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls; type TForm1 = class(TForm) procedure FormCreate(Sender: TObject); private LDLLHandle: HModule; LShowProc: TProcedure; end; var Form1: TForm1; {$ifdef static} procedure MyInit; stdcall; external 'dll.dll'; {$endif} implementation {$R *.dfm} procedure TForm1.FormCreate(Sender: TObject); begin TStringList.Create; {$ifdef static} MyInit; {$else} LDLLHandle := LoadLibrary('dll.dll'); if LDLLHandle <> 0 then begin try LShowProc := GetProcAddress(LDLLHandle, 'MyInit'); if Assigned(LShowProc) then LShowProc; finally FreeLibrary(LDLLHandle); end; end; {$endif} end; end. ``` I expect from FastMM to generate a report when FreeLibrary is called, or on program exit, if the dll is statically loaded, but nothing happens. In the `FastMM4Options.inc` I additionally just set FullDebugMode and ClearLogFileOnStartup, and the FastMM_FullDebugMode.dll is in the output directory. I created a repository on github. What am I missing?

Original source