2013-07-04 55 views
7

我无法弄清楚如何检测静态或甚至动态链接的DLL中的内存泄漏。我只是想检测DLL中的泄漏,我不想在DLL和应用程序之间共享内存管理器。此外,该DLL是与运行时包联如何配置FastMM来检测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. 

我从FastMM希望生成报表时FreeLibrary则是所谓的,或者在程序退出,如果DLL静态加载,但没有任何反应。

FastMM4Options.inc我还只设置FullDebugModeClearLogFileOnStartupFastMM_FullDebugMode.dll是在输出目录。

我创建了一个repository on github。我错过了什么?

+0

奇怪...你刚刚克隆回购,并运行,它在xe3上工作? – balazs

+0

当我建立自己的项目时,我无法再现。但我用我自己的fastmm选项。但是,我把你的项目,可以回购,现在已经解决了这个问题。 –

回答

5

的原因,你的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} 
); 

在你的选择,RequireDebuggerPresenceForLeakReporting定义。更重要的是,在DLL中,DebugHook等于0,大概是因为你正在调试应用程序而不是DLL。这意味着您致电CheckBlocksOnShutdown通过False。并且False禁用泄漏报告。

您可以通过取消定义RequireDebuggerPresenceForLeakReporting来解决此问题。

+0

我得到了有关RequireDebuggerPresenceForLeakReporting的fastMM泄漏报告禁用,ShareMM禁用和AttemtToUseSharedMM禁用 – Ravaut123

+0

@ Ravaut123正如我在答案中所述,停止泄漏报告的单一因素balazs'项目是定义了'RequireDebuggerPresenceForLeakReporting'。 –

+0

是的,我upvote你的答案 – Ravaut123

-1

我只是版本快速内存管理器4.97测试它Delphi2010 - WIN7

  1. FastMM4是第一单元的.dpr的 '用途' 条款(项目和dll)
  2. 'ShareMM' 在
  3. 'AttemptToUseSharedMM' 选项启用选项启用
  4. 'EnableMemoryLeakReporting' 选项启用

在exe文件夹中添加FastMM_FullDebugMode.dll

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

+0

为什么你启用Sharemem?考虑到提问者明确表示他不想使用Sharemem。 –

+0

我的项目测试DLL是由memshare。所以我也在 – Ravaut123

+0

上测试memshare这对你很好。但是,为什么你不试图与问题中描述的场景相匹配呢? –