How to configure FastMM to detect memory leak in a dll
Asked Answered
D

2

7

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?

Decillion answered 4/7, 2013 at 18:55 Comment(2)
strange... Did you just clone the repo, and run and it works on xe3?Decillion
I could not repro when I built my own project. But I used my own fastmm options. However, I took your project, could repo, and have now solved the problem.Morsel
M
6

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.

Morsel answered 5/7, 2013 at 10:26 Comment(3)
I get leak reports of the fastMM with RequireDebuggerPresenceForLeakReporting Disable, ShareMM Disable and AttemtToUseSharedMM DisableAltis
@Altis As I stated in the answer, the single factor that was stopping leak reports in the balazs' project was that RequireDebuggerPresenceForLeakReporting was defined.Morsel
Thanks, it's working like a charm both with statically and dinamically loaded dll.Decillion
A
-1

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.

Altis answered 5/7, 2013 at 8:4 Comment(8)
Why did you enable Sharemem? Consider that the asker explicitly stated that he did not want to use Sharemem.Morsel
My Project to test the dll was made with memshare. So I also test the memshare onAltis
That's nice for you. But why don't you try to match the scenario described in the question?Morsel
Also test the demo 'Dynamically Loaded DLL' of FastMM. And this to the job also. Without ShareMem ;-)Altis
Thanks for your response, but as @DavidHeffernan said I don't want to share the memory manager. I could make it work that way, see this github repo, By the way, I put FastMM into a separate package, which is used by the app and the dll, so I got full stack traces for leaks in the dll too. Now I'm interested in how to do it without sharing.Decillion
@balazs: I don't declare the ShareMem in my project or dll. I just set it enable in the options of FastMM.Altis
I believe If you enbale ShareMM than the FastMM memory manager is shared between the dll and the app.Decillion
It was not from me, I'm glad you spent time with my problem. It's not the answer to my question, however I think it'll be useful for others.Decillion

© 2022 - 2024 — McMap. All rights reserved.