简体   繁体   English

BTMemoryModule 中的 Delphi 内存泄漏

[英]Delphi memory leak in BTMemoryModule

testing for memory leaks with madhi's madExcept, and the unit BTMemoryModule to load DLLs straight to ram from a resource, it's reporting leaks here:使用 madhi 的 madExcept 和单元BTMemoryModule测试内存泄漏以将 DLL 直接从资源加载到 ram,它在此处报告泄漏:

How could this be fixed?这怎么能解决?

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.

How to reproduce:如何重现:

  • Enable madExcept with the option to report resource leaks使用报告资源泄漏的选项启用 madExcept
  • Add any DLL in the project resources (in my case unrar.dll) with RCDATA name UNRARDLL使用 RCDATA 名称 UNRARDLL 在项目资源(在我的情况下为 unrar.dll)中添加任何 DLL
  • Start and close the app启动和关闭应用程序

Another company made a working DLL loader that does NOT leak memory.另一家公司制作了一个不会泄漏内存的工作 DLL 加载程序。 The sources are in IPWCore.pas in IPWork's Internet (Components) Delphi Edition that comes with all versions of Delphi.源代码位于 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