2013-07-04 61 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這對你很好。但是,爲什麼你不試圖與問題中描述的場景相匹配呢? –