3

I have a simple Application that reads data from an .ini file into a record, and then does a ShellExecute. However, when I run it in debug mode,it tells me that the True free heap isn't what it should be:

"True heap size: 688128, True free heap: 688016, Should be: 688128"

Heaptrc message

This only happens if I actually run the ShellExecute (however even if I don't run the ShellExecute, I get a True free heap of 688016, but no complaint that it should be 688128), so I wonder if I either need to free the PChar() conversion (which shouldn't be the case from all that I've read), or the handle returned by ShellExecute (though CloseHandle(ShellHandle); doesn't change the message), or if it's intended behavior?

The IniSettings.SetupCommand in question is an .msi file that triggers a UAC prompt, but I really just want to make this a Fire & Forget thing since my Lazarus app doesn't care what it launches.

For reference, here's my whole Unit. I'm using Lazarus 1.6.2, FPC 3.0.0, i386-win32, and I'm targeting Windows only with this. My Debug Settings are at the very bottom, after the code.

unit MainUnit;   

{$mode objfpc}{$H+}    

interface    

uses
  Classes, SysUtils, FileUtil, Forms, Controls,
  Graphics, Dialogs, StdCtrls, IniFiles, Windows;

type
  { IniSettings }
  TAutorunIniSettings = record
    AutorunTitle: AnsiString;
    SetupCommand: AnsiString;
  end;

  { TMainForm }
  TMainForm = class(TForm)
    btnSetup: TButton;
    lblTitle: TLabel;
    procedure btnSetupClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { private declarations }
    IniSettings: TAutorunIniSettings;
  public
    { public declarations }
  end;

var
  MainForm: TMainForm;

implementation

{$R *.lfm}

{ TMainForm }

procedure TMainForm.FormCreate(Sender: TObject);
var
  AutorunIni: TIniFile;
begin
  try
    AutorunIni := TIniFile.Create('Autorun.ini');
    IniSettings.AutorunTitle := AutorunIni.ReadString('Autorun', 'Title', 'Autorun');
    IniSettings.SetupCommand := AutorunIni.ReadString('Autorun', 'Setup', '');

    self.Caption := IniSettings.AutorunTitle;
  finally
    if(AutorunIni <> nil) then AutorunIni.Free;
  end;
end;

procedure TMainForm.FormDestroy(Sender: TObject);
begin

end;

procedure TMainForm.btnSetupClick(Sender: TObject);
begin
     ShellExecute(0, 'open', PChar(IniSettings.SetupCommand), nil, nil, SW_SHOWNORMAL);
end;

end.

Lazarus Debug Settings

Michael Stum
  • 177,530
  • 117
  • 400
  • 535
  • 1
    I can duplicate your issue, with a simpler case. Anything you can think of that cause "windows.pp" linked. Nothing related to ShellExecute, for instance IsWindow(Handle) does the same, even if you don't call it. Obviously something leaks out of the RTL, or so the debugger thinks. – Sertac Akyuz Dec 28 '16 at 15:42
  • @SertacAkyuz Thanks. I'll try one of the non-Windows related [ways to launch](http://wiki.freepascal.org/Executing_External_Programs) instead to see if that makes the error go away, – Michael Stum Dec 28 '16 at 15:44
  • No real luck. Since I'm trying to run an .msi file, ShellExecute is really what I want. `LCLIntf.OpenDocument` results in the same leak, but that seems to be using Windows under the hood. For now, since the True Heap Size is the same whether I run `ShellExecute` or not, I assume it might be a bug in Heaptrc. – Michael Stum Dec 28 '16 at 15:59
  • 1
    I can't leak anymore without ShellExecute, or without calling it. I don't know what I did before. Anyway, it is a one time leak, how many times you call ShellExecute does not matter. It's also the same amount (160 here) written in parenthesis "near true heap size" that's said to be used in system startup when there's no leak. I wouldn't be concerned... – Sertac Akyuz Dec 28 '16 at 16:26
  • 2
    There is no memory leak at all. The heaptrc output is a bit confusing, but the important line to look at is "0 unfreed memory blocks: 0" - this means that every memory block allocated by the program has been released. – wp_1233996 Dec 28 '16 at 17:38

0 Answers0