2013-07-04 13 views
7

Nie mogę wymyślić, jak wykryć wycieki pamięci w statycznie lub nawet dynamicznie podłączonej bibliotece dll. Po prostu chcę wykryć wycieki w bibliotece DLL i nie chcę udostępniać menedżera pamięci między biblioteką DLL a aplikacją. Dodatkowo dll jest związane z pakietami uruchomieniowychJak skonfigurować FastMM, aby wykryć wyciek pamięci w bibliotece dll

Moje dll próbka wygląda następująco:

library dll; 
uses 
    fastmm4, 
    System.SysUtils, 
    System.Classes; 
{$R *.res} 
procedure MyInit; stdcall; 
Begin 
    TObject.Create; 
End; 
exports MyInit; 
begin 
end. 

DPR zastosowanie:

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. 

Uwaga: Jeśli odkomentowaniu fastmm4, niż mogę wykryć memleak spowodowane przez aplikację (TStringList.Create), ale nie wyciek w bibliotece dll.

A w jednostce głównej aplikacji:

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. 

Oczekuję od FastMM wygenerować raport po FreeLibrary nazywa, albo na wyjściu z programu, jeśli biblioteka DLL jest ładowany statycznie, ale nic się nie dzieje.

W FastMM4Options.inc ja dodatkowo wystarczy ustawić FullDebugMode i ClearLogFileOnStartup, a FastMM_FullDebugMode.dll znajduje się w katalogu wyjściowym.

Utworzono repository on github. czego mi brakuje?

+0

Dziwne ... Czy po prostu sklonowałeś repozytorium i uruchomiłeś to na xe3? – balazs

+0

Nie mogłem repro, gdy zbudowałem swój własny projekt. Użyłem jednak własnych opcji fastmm. Jednak wziąłem twój projekt, mogłem zrobić repozytorium i rozwiązać ten problem. –

Odpowiedz

5

Powodem że DLL nie donosi przecieków wynika z tego kodu w zamknięciu 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} 
); 

W opcjach, RequireDebuggerPresenceForLeakReporting jest zdefiniowana. Co więcej, w DLL, DebugHook jest równa 0, prawdopodobnie dlatego, że debugujesz aplikację zamiast DLL. Oznacza to, że dzwonisz pod numer CheckBlocksOnShutdown, mijając False. I że False wyłącza zgłaszanie wycieków.

Możesz rozwiązać ten problem, niezdefiniowując wartość RequireDebuggerPresenceForLeakReporting.

+0

Otrzymuję raporty o wycieku fastMM z RequireDebuggerPresenceForLeakReporting Disable, ShareMM Disable and AttemtToUseSharedMM Disable – Ravaut123

+0

@ Ravaut123 Jak stwierdziłem w odpowiedzi, jeden czynnik, który zatrzymywał raporty o wyciekach w Projekt balazs polegał na zdefiniowaniu 'RequireDebuggerPresenceForLeakReporting'. –

+0

Tak, i przejąłem twoją odpowiedź – Ravaut123

-1

po prostu przetestować go z wersji menedżera szybkiej pamięci 4.97 na Delphi2010 - win7

  1. FastMM4 to pierwsza jednostka w klauzuli '' korzysta z .dpr (projekt i DLL)
  2. 'ShareMM' opcja jest włączona
  3. opcja 'AttemptToUseSharedMM' jest włączona
  4. opcja 'EnableMemoryLeakReporting' jest włączona

Dodaj plik FastMM_FullDebugMode.dll do folderu exe

Dostępne jest również demo testowe "Dynamically Loaded DLL" To demo jest bez ShareMem. Muszę ustawić opcję "ShareMM" i "AttemptToUseSharedMM" włączone i dodać FastMM_FullDebugMode.dll, aby mieć raport o wycieku FastMM.

+0

Dlaczego aktywowałeś Sharemem? Uważają, że osoba pytająca wyraźnie stwierdziła, że ​​nie chce używać Sharemem. –

+0

Mój projekt do przetestowania biblioteki dll został złożony z memshare. Więc testuję także zapamiętywanie na – Ravaut123

+0

To miło dla ciebie. Ale dlaczego nie spróbujesz dopasować scenariusza opisanego w pytaniu? –