2013-07-04 3 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. 

응용 프로그램의 조선 민주주의 인민 공화국 :

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. 

내가 DLL이 정적으로로드 된 경우 FreeLibrary를가,라고, 또는 프로그램 종료에 때 보고서를 생성 FASTMM 기대하지만 아무 일도 일어나지 않습니다. FastMM4Options.inc에서

나는 또한 단지 ClearLogFileOnStartupFullDebugMode을 설정하고, FastMM_FullDebugMode.dll 출력 디렉토리에 있습니다.

나는 repository on github을 만들었습니다. 내가 뭘 놓치고 있니?

+0

이상한 ... 그냥 repo를 복제하고 실행하고 xe3에서 작동합니까? – balazs

+0

나 자신의 프로젝트를 만들 때 나는 재현 할 수 없었다. 그러나 나는 내 자신의 fastmm 옵션을 사용했습니다. 그러나, 나는 당신의 프로젝트를 가져 갔고, repo 할 수 있었고, 지금 문제를 해결했다. –

답변

5

이유는 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

RequireDebuggerPresenceForLeakReporting Disable, ShareMM Disable 및 AttemtToUseSharedMM을 사용하여 fastMM의 누수 보고서가 표시됩니다. – 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의 누수보고를해야합니다. 당신의 DLL이 누수가보고되지

+0

Sharemem을 사용하도록 설정 한 이유가 무엇인가요? 질문자가 Sharemem을 사용하고 싶지 않다고 명시 적으로 진술했다고 생각하십시오. –

+0

dll을 테스트하는 프로젝트는 memshare로 만들었습니다. 그래서 나는 또한 – Ravaut123

+0

에 memshare를 테스트합니다. 하지만 질문에 설명 된 시나리오와 일치 시키려하지 않는 이유는 무엇입니까? –