簡體   English   中英

BTMemoryModule 中的 Delphi 內存泄漏

[英]Delphi memory leak in BTMemoryModule

使用 madhi 的 madExcept 和單元BTMemoryModule測試內存泄漏以將 DLL 直接從資源加載到 ram,它在此處報告泄漏:

這怎么能解決?

type: VirtualAlloc  
    address: $71d1000  
    size: 177664  
    access rights: ./.

    main thread ($1134):  
    671cd432 madExcept32.dll madExceptDbg 2511 VirtualAllocCallback  
    006a8694 x.exe BTMemoryModule 196 CopySections  
    006a8cee x.exe BTMemoryModule 418 BTMemoryLoadLibary

    type: VirtualAlloc  
    address: $71d0000  
    size: 262144  
    access rights: ./.

    main thread ($1134):  
    671cd432 madExcept32.dll madExceptDbg 2511 VirtualAllocCallback  
    006a8ca4 x.exe BTMemoryModule 409 BTMemoryLoadLibary

    type: VirtualAlloc  
    address: $71d0000  
    size: 262144  
    access rights: ./.

    main thread ($1134):  
    671cd432 madExcept32.dll madExceptDbg 2511 VirtualAllocCallback  
    006a8c3f x.exe BTMemoryModule 396 BTMemoryLoadLibary
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, BTMemoryModule;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
  public
  end;

Const UnrarLibDLL = 'UNRARDLL';

var
  Form1: TForm1;
  rStream: TResourceStream;
  mp_MemoryModule: PBTMemoryModule;
  mp_DllData: Pointer;
  m_DllDataSize: Integer;

implementation

{$R *.dfm}

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  if m_DllDataSize > 0 then FreeMemory( mp_DllData );
  if mp_MemoryModule <> nil then BTMemoryFreeLibrary( mp_MemoryModule );
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  rStream := TResourceStream.Create( HInstance, UnrarLibDLL, RT_RCDATA );
  try
    m_DllDataSize := rStream.Size;
    mp_DllData    := GetMemory( m_DllDataSize );
    rStream.Read( mp_DllData^, m_DllDataSize );
  finally
    rStream.Free;
  end;

  mp_MemoryModule := BTMemoryLoadLibary( mp_DllData, m_DllDataSize );
end;

end.

如何重現:

  • 使用報告資源泄漏的選項啟用 madExcept
  • 使用 RCDATA 名稱 UNRARDLL 在項目資源(在我的情況下為 unrar.dll)中添加任何 DLL
  • 啟動和關閉應用程序

另一家公司制作了一個不會泄漏內存的工作 DLL 加載程序。 源代碼位於 IPWork 的 Internet(組件)Delphi 版本中的 IPWCore.pas 中,該版本隨所有版本的 Delphi 一起提供。

interface
uses IPWcore;
...
type
  _FunctionDLL = function: integer; stdcall;

var
  pEntryPoint: Pointer;
  pBaseAddress: Pointer;
  FunctionDLL: _FunctionDLL;

implementation

procedure TYourForm.FormCreate;
var
  hResInfo: HRSRC;
  hResData: HGLOBAL;
  pResData: Pointer;
begin
  hResInfo := FindResource(HInstance, 'EMVDLL', RT_RCDATA);
  hResData := LoadResource(HInstance, hResInfo);
  if hResData = 0 then
    exit;
  pResData := LockResource(hResData);
  if pResData = nil then
    exit;
  
  pBaseAddress := IPWorksLoadDRU(pResData, pEntryPoint);
  @FunctionDLL := IPWorksFindFunc(pBaseAddress, 'Function');
  ...
end;

procedure TYourForm.FormDestroy(Sender: TObject);
begin
  IPWorksFreeDRU(pBaseAddress, pEntryPoint);
  pBaseAddress := nil;
  pEntryPoint := nil;
end;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM