Delphi 如何配置FastMM以检测dll中的内存泄漏

Delphi 如何配置FastMM以检测dll中的内存泄漏,delphi,dll,delphi-xe3,fastmm,Delphi,Dll,Delphi Xe3,Fastmm,我不知道如何在静态或动态链接的dll中检测内存泄漏。我只想检测dll中的泄漏,不想在dll和应用程序之间共享内存管理器。此外,dll与运行时包链接 我的示例dll如下所示: library dll; uses fastmm4, System.SysUtils, System.Classes; {$R *.res} procedure MyInit; stdcall; Begin TObject.Create; End; exports MyInit; begin end. 应用

我不知道如何在静态或动态链接的dll中检测内存泄漏。我只想检测dll中的泄漏,不想在dll和应用程序之间共享内存管理器。此外,dll与运行时包链接

我的示例dll如下所示:

library dll;
uses
  fastmm4,
  System.SysUtils,
  System.Classes;
{$R *.res}
procedure MyInit; stdcall;
Begin
  TObject.Create;
End;
exports MyInit;
begin
end.
应用程序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.
注意:如果我取消注释fastmm4,那么我可以检测到由应用程序(TStringList.Create)引起的memleak,但不能检测dll中的泄漏

在应用程序主单元中:

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.
unitmain;
接口
使用
Winapi.Windows、Winapi.Messages、System.SysUtils、System.Variants、System.Classes、Vcl.Graphics、,
Vcl.控件、Vcl.窗体、Vcl.对话框、Vcl.stdctrl;
类型
TForm1=类(TForm)
过程表单创建(发送方:ToObject);
私有的
LDLLHandle:HModule;
LShowProc:t过程;
结束;
变量
表1:TForm1;
{$ifdef static}
程序MyInit;stdcall;外部“dll.dll”;
{$endif}
实施
{$R*.dfm}
过程TForm1.FormCreate(发送方:TObject);
开始
创造;
{$ifdef static}
肌炎;
{$else}
LDLLHandle:=LoadLibrary('dll.dll');
如果LDLLHandle为0,则
开始
尝试
LShowProc:=GetProcAddress(LDLLHandle,'MyInit');
如果已分配(LShowProc),则
LShowProc;
最后
免费图书馆;
结束;
结束;
{$endif}
结束;
结束。
我希望在调用FreeLibrary时,或者在程序退出时,如果dll是静态加载的,FastMM会生成一个报告,但什么也不会发生

FastMM4Options.inc
中,我另外刚刚设置了FullDebugModeClearLogFileOnStartup,并且FastMM\u FullDebugMode.dll在输出目录中


我创建了一个。我遗漏了什么?

我只是在Delphi2010-win7上用版本Fast Memory Manager 4.97进行了测试

  • FastMM4是.dpr(项目和dll)的“uses”子句中的第一个单元
  • “ShareMM”选项已启用
  • “AttemptouseSharedMM”选项已启用
  • “EnableMemoryLeakReporting”选项已启用
  • 将FastMM_FullDebugMode.dll添加到exe文件的文件夹中

    还有一个测试演示“动态加载的DLL” 此演示没有ShareMem。
    我必须启用“ShareMM”和“AttemptouseSharedMM”选项,并添加FastMM_FullDebugMode.dll,以生成FastMM的泄漏报告。

    您的dll不报告泄漏的原因源于FastMM关机时的以下代码:

      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}
      );
    
    CheckBlocksOnShutdown(
    {$ifdef EnableMemoryLeakReporting}
    真的
    {$ifdef RequiremeDepresseEnferleAkReporting}
    而且正在运行
    {$endif}
    {$ifdef requiredBuggerPresenceforLeakReporting}
    和((0)
    {$ifdef PatchBCBTerminate}
    或(已分配(pCppDebugHook)和(pCppDebugHook^0))
    {$endif PatchBCBTerminate}
    )
    {$endif}
    {$ifdef ManualLeakReportingControl}
    和报告MemoryleaksonShutdown
    {$endif}
    {$else}
    假的
    {$endif}
    );
    
    在您的选项中,定义了泄漏报告所需的BuggerPresence。此外,在DLL中,
    DebugHook
    等于
    0
    ,可能是因为您正在调试应用程序而不是DLL。这意味着您调用
    CheckBlocksOnShutdown
    传递
    False
    。而且
    False
    会禁用泄漏报告


    您可以通过取消定义LeakReporting的RequiredBuggerPresence来解决此问题

    为什么启用Sharemem?考虑到Ask明确声明他不想使用SaleMeM。我的测试DLL的项目是用MyScript制作的。我还测试了memshare,这对你很好。但是为什么不尝试匹配问题中描述的场景呢?还要测试FastMM的演示“动态加载的DLL”。这也与工作有关。没有ShareMem;-)感谢您的回复,但正如@DavidHeffernan所说,我不想共享内存管理器。我可以让它这样工作,顺便说一句,我把FastMM放在一个单独的包中,由应用程序和dll使用,所以我也得到了dll中泄漏的完整堆栈跟踪。现在我对如何在没有分享的情况下做到这一点很感兴趣。奇怪。。。你刚刚克隆了回购协议并在xe3上运行了吗?当我构建自己的项目时,我无法重新编程。但我使用了自己的fastmm选项。但是,我接受了你的项目,可以重新发布,现在已经解决了这个问题。我得到了fastMM的泄漏报告,其中包含LeakReporting Disable、ShareMM Disable和AttemTouseSharedMM所需的BuggerPresenceDisable@Ravaut123正如我在答覆中所说,,在balazs的项目中阻止泄漏报告的唯一因素是定义了泄漏报告的
    RequiredBuggerPresence
    。谢谢,它在静态和动态加载的dll中都发挥了巨大的作用。