2013-07-04 6 views
7

静的にまたは動的にリンクされたdllでメモリリークを検出する方法がわかりません。私はDLL内のリークを検出したいだけで、DLLとアプリケーションの間でメモリマネージャを共有したくありません。さらに、dllががdllでメモリリークを検出するようにFastMMを構成する方法

マイサンプル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を、コメントを解除した場合アプリケーションによって引き起こされるmemleak(TStringList.Create)が、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. 

私はFreeLibraryのが呼ばれ、またはプログラム終了時に、DLLが静的にロードされている場合、何も起こりませんされたレポートを生成するためにFastMMから期待しています。私は、さらにちょうどFullDebugModeClearLogFileOnStartupを設定し、FastMM_FullDebugMode.dllは、出力ディレクトリにあるFastMM4Options.inc

私は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では、DebugHook0と等しくなります。おそらく、DLLではなくアプリケーションをデバッグしているからです。つまり、CheckBlocksOnShutdownにはFalseが渡されます。そして、Falseはリークの報告を無効にします。

これを解決するには、RequireDebuggerPresenceForLeakReportingを定義しないでください。

+0

FastMMのリークレポートを取得するためにRequireDebuggerPresenceForLeakReporting Disable、ShareMM Disable、AttemtToUseSharedMMを無効にしてください – Ravaut123

+0

@ Ravaut123答えとして述べたように、 balazs 'プロジェクトでは、RequireDebuggerPresenceForLeakReportingが定義されていました。 –

+0

ええと、私はあなたの答えをupvote – Ravaut123

-1

私はDelphi2010にバージョン高速メモリマネージャ4.97でそれをテストする - win7の

  1. FastMM4が.DPR(プロジェクトおよびDLL)
  2. の '用途' 句の最初の単位である 'ShareMM'
  3. 'AttemptToUseSharedMM' オプションが有効になっている
  4. オプションが有効になっている
  5. 'EnableMemoryLeakReporting' オプションが有効になっている

exeのフォルダにFastMM_FullDebugMode.dllを追加してください

また、「Dynamically Loaded DLL」というテストデモもあります。 このデモにはShareMemがありません。 オプション 'ShareMM'と 'AttemptToUseSharedMM'を有効にし、FastMM_FullDebugMode.dllを追加して、FastMMのリークレポートを作成する必要があります。

+0

Sharememを有効にしたのはなぜですか?質問者がSharememを使いたくないと明言したと考えてください。 –

+0

DLLをテストするプロジェクトはmemshareで作成されました。だから私も – Ravaut123

+0

にmemshareをテストするそれはあなたのためにいいです。しかし、あなたは質問に記載されているシナリオに合ってみてはどうですか? –

関連する問題