Question

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?

Was it helpful?

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.

OTHER TIPS

I just test it with version Fast Memory Manager 4.97 on Delphi2010 - win7

  1. FastMM4 is the first unit in the 'uses' clause of the .dpr (project and dll)
  2. 'ShareMM' option is enabled
  3. 'AttemptToUseSharedMM' option is enabled
  4. 'EnableMemoryLeakReporting' option is enabled

Add FastMM_FullDebugMode.dll in the folder of the exe

There is also a test demo 'Dynamically Loaded DLL' This demo is without the ShareMem. I must set the option 'ShareMM' and 'AttemptToUseSharedMM' enabled and add the FastMM_FullDebugMode.dll to have a leak report of FastMM.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top