2013-07-04 10 views
7

Non riesco a capire come rilevare perdite di memoria in una DLL staticamente o addirittura dinamicamente collegata. Voglio solo rilevare le perdite nella DLL e non voglio condividere il gestore della memoria tra la DLL e l'app. Inoltre la dll è collegato con i pacchetti runtimeCome configurare FastMM per rilevare la perdita di memoria in una DLL

mio dll campione si presenta così:

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

applicazione 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. 

Nota: Se io Decommentare fastmm4, di quanto io possa rilevare la memleak causato dall'applicazione (TStringList.Create), ma non dalla perdita nella dll.

E nell'unità principale dell'applicazione:

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. 

mi aspetto da FastMM per generare un rapporto quando FreeLibrary si chiama, o all'uscita del programma, se la DLL viene caricata in modo statico, ma non succede nulla.

Nel FastMM4Options.inc ho inoltre appena impostato FullDebugMode e ClearLogFileOnStartup, e il FastMM_FullDebugMode.dll si trova nella directory di output.

Ho creato un repository on github. Cosa mi manca?

+0

strano ... Hai appena clonato il repository e corri e funziona su xe3? – balazs

+0

Non ho potuto riprodurre quando ho costruito il mio progetto. Ma ho usato le mie opzioni fastmm. Tuttavia, ho preso il tuo progetto, ho potuto fare un repo e ora ho risolto il problema. –

risposta

5

La ragione per cui la DLL non sta inviando rapporti perdite deriva da questo codice nella arresto 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} 
); 

Nelle opzioni, RequireDebuggerPresenceForLeakReporting è definito. Cosa c'è di più, nella DLL, DebugHook è uguale a 0, presumibilmente perché si sta eseguendo il debug dell'applicazione anziché della DLL. Ciò significa che chiami CheckBlocksOnShutdown passando False. E che False disabilita la segnalazione di perdite.

È possibile risolvere ciò indefinendo RequireDebuggerPresenceForLeakReporting.

+0

Ottengo rapporti di perdita del fastMM con RequireDebuggerPresenceForLeakReporting Disabilita, ShareMM Disable e AttemtToUseSharedMM Disabilita – Ravaut123

+0

@ Ravaut123 Come ho affermato nella risposta, il singolo fattore che stava bloccando i report di perdita nel Il progetto di balazs era definito come RequireDebuggerPresenceForLeakReporting'. –

+0

Sì, e ho votato in anticipo la tua risposta – Ravaut123

-1

ho appena prova con la versione Fast Memory Responsabile 4,97 su Delphi2010 - win7

  1. FastMM4 è la prima unità nella clausola 'usi' del .dpr (progetto e dll)
  2. 'ShareMM' opzione è abilitata
  3. opzione 'AttemptToUseSharedMM' è abilitato
  4. opzione 'EnableMemoryLeakReporting' è abilitato

Aggiungi FastMM_FullDebugMode.dll nella cartella del exe

C'è anche una demo di prova 'Dynamically Loaded DLL' Questa demo è senza ShareMem. Devo impostare l'opzione 'ShareMM' e 'AttemptToUseSharedMM' abilitata e aggiungere FastMM_FullDebugMode.dll per avere un rapporto sulle perdite di FastMM.

+0

Perché hai abilitato Sharemem? Considera che il richiedente ha esplicitamente dichiarato che non voleva usare Sharemem. –

+0

Il mio progetto per testare la dll è stato realizzato con memshare. Così provo anche il memshare su – Ravaut123

+0

Questo è bello per te. Ma perché non provi ad abbinare lo scenario descritto nella domanda? –