Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2016-10

Generic way to pre-maturely exit TCustomApplication without memory leaks

17 messages · 7 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

grouchysmurf

Hi.

Is there a way to pre-maturely halt TCustomApplication without causing memory leaks?

Say, I have a code, where TH is a Class(TCustomApplication):

  ph := TH.Create(Nil);
  ph.Initialize;
  ph.ProcessOptions;
  ph.Run;
  ph.Free;

When options are processed, it may happen the program needs to halt, when provided with improper parameters, for example. In such a case, I would call Help method:

Procedure TH.Help(ExitCode : Byte = 0; ErrStr : String = '');
Begin
{ do stuff }
  Halt(ExitCode);
End;

Now, when this happens, ph is not freed, causing a minor memory leak. I don't want that. Is there a way to terminate a program with Halt but also making sure the memory has been freed properly?

Thanks.

Łukasz

Reply by email

Michael Van Canneyt
to grouchysmurf
grouchysmurf wrote 27 lines
Hi. Is there a way to pre-maturely halt TCustomApplication without causing memory leaks? Say, I have a code, where TH is a Class(TCustomApplication): ph := TH.Create(Nil); ph.Initialize; ph.ProcessOptions; ph.Run; ph.Free; When options are processed, it may happen the program needs to halt, when provided with improper parameters, for example. In such a case, I would call Help method: Procedure TH.Help(ExitCode : Byte = 0; ErrStr : String = ''); Begin { do stuff } Halt(ExitCode); End; Now, when this happens, ph is not freed, causing a minor memory leak. I don't want that. Is there a way to terminate a program with Halt but also making sure the memory has been freed properly?

Call Terminate and exit properly ?
TCustomApplication has an exitcode property which will set the global exit code.

Michael.

Reply by email

Graeme Geldenhuys
to grouchysmurf: Hi. Is there a way to pre-maturely halt TCustomApplication without causing memory leaks?…
grouchysmurf wrote 7 lines
Say, I have a code, where TH is a Class(TCustomApplication): ph := TH.Create(Nil); ph.Initialize; ph.ProcessOptions; ph.Run; ph.Free;

I would also rewrite that with a try..finally as in:

ph := TH.Create(nil)
try
  ph.Initialize;
  ph.ProcessOptions;
  ph.Run;
finally
  ph.Free;
end;

Regards,
Graeme

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/ My public PGP key: http://tinyurl.com/graeme-pgp

Reply by email

Bart
to Michael Van Canneyt: Call Terminate and exit properly ? TCustomApplication has an exitcode property which will…
Michael Van Canneyt wrote
Call Terminate and exit properly ? TCustomApplication has an exitcode property which will set the global exit code.

AFAICS not in fpc 3.0.0

(TATCApp = class(TCustomApplication)

procedure TATCApp.OnExcept(Sender: TObject; E: Exception);
begin
  writeln(Format('An exception has occurred of type %s, with
message:',[E.ClassName]));
  writeln(Format('"%s"',[E.Message]));
  writeln('The program will be termminated immediately.');
  if (E is EInOutError) then Self.ExitCode := EInOutError(E).ErrorCode;
end;
air2.lpr(54,35) Error: identifier idents no member "ExitCode"

Probably you can set system.ExitCode before calling Terminate.

Bart

Reply by email

Santiago A.
to Graeme Geldenhuys: I would also rewrite that with a try..finally as in: ph := TH.Create(nil) try…
Graeme Geldenhuys wrote 9 lines
I would also rewrite that with a try..finally as in: ph := TH.Create(nil) try ph.Initialize; ph.ProcessOptions; ph.Run; finally ph.Free; end;

May be I'm wrong, but I think that Halt(n) is a nuclear bomb, it closes the application almost on the current instruction, "finally" and "except" blocks are not executed. Nevertheless, Finalization blocks are executed.

Anyway, I think that when the application is closed all the allocated memory is freed, memory leaks survive as long as the application is running. So wondering about what's in memory after a halt makes no sense, everything is freed.

Saludos Santiago A.

Reply by email

Sven Barth
to Graeme Geldenhuys: I would also rewrite that with a try..finally as in: ph := TH.Create(nil) try…

Am 13.10.2016 10:09 schrieb "Graeme Geldenhuys" <

Show quoted text 22 lines
: On 2016-10-12 20:37, grouchysmurf wrote: > Say, I have a code, where TH is a Class(TCustomApplication): > > ph := TH.Create(Nil); > ph.Initialize; > ph.ProcessOptions; > ph.Run; > ph.Free; I would also rewrite that with a try..finally as in: ph := TH.Create(nil) try ph.Initialize; ph.ProcessOptions; ph.Run; finally ph.Free; end;

That won't help with Halt() however as that will "jump" directly to the unit finalization, ignoring any and all exception handlers along the way.

Regards,
Sven

Reply by email

Graeme Geldenhuys
to Sven Barth
Sven Barth wrote
That won't help with Halt() however as that will "jump" directly to the unit finalization, ignoring any and all exception handlers along the way.

Wow, that's a bit harsh. Overriding the whole meaning of the try..finally language feature. Then I would recommend NOT using Halt() for anything - its nasty.

Regards,
Graeme

Reply by email

Sven Barth
to Graeme Geldenhuys

Am 13.10.2016 15:07 schrieb "Graeme Geldenhuys" <

Show quoted text 5 lines
: On 2016-10-13 13:48, Sven Barth wrote: > That won't help with Halt() however as that will "jump" directly to the > unit finalization, ignoring any and all exception handlers along the

way.

Show quoted text 6 lines
Wow, that's a bit harsh. Overriding the whole meaning of the try..finally language feature. Then I would recommend NOT using Halt() for anything - its nasty.

You must not forget that it came from a time when Pascal didn't have exception handling. Nowadays it's indeed more often than not better not to use it due to the way it works.

Regards,
Sven

Reply by email

grouchysmurf
to Michael Van Canneyt: Call Terminate and exit properly ? TCustomApplication has an exitcode property which will…

Hi.

Call Terminate and exit properly ? TCustomApplication has an exitcode property which will set the global exit code.

This feature either undocumented or I am just too stupid to find it. Mind if I ask you to point me directly to the documentation?

I believe it would have to be something as follows:

ph.Terminate(ExitCode);
ph.Free;

if I am reading you correctly. Currently, if I call Terminate(1), it compiles with following error:

Error: Wrong number of parameters specified for call to "Terminate"

Would appreciate any help.

Łukasz

Reply by email

grouchysmurf
to Santiago A.: May be I'm wrong, but I think that Halt(n) is a nuclear bomb, it closes the application…

Hi.

Anyway, I think that when the application is closed all the allocated memory is freed, memory leaks survive as long as the application is running. So wondering about what's in memory after a halt makes no sense, everything is freed.

I am not very familiar with internals of system programming.

Dump follows:

Heap dump by heaptrc unit
73 memory blocks allocated : 1872/2048
70 memory blocks freed : 1733/1896
3 unfreed memory blocks : 139
True heap size : 327680 (96 used in System startup) True free heap : 327216
Should be : 327240
Call trace for block $014B4DC0 size 34
$00401A9A
$00401BAE
$0050005C
$006F0072
$00720067
$006D0061
$00460020
$006C0069
Call trace for block $014AD820 size 17
$00401BAE
$00401BAE
Call trace for block $014DCBB8 size 88
$00401B8C

Not that I know that to do with this data.

Łukasz

Reply by email

Santiago A.
to Graeme Geldenhuys: Wow, that's a bit harsh. Overriding the whole meaning of the try..finally language…
Graeme Geldenhuys wrote 7 lines
On 2016-10-13 13:48, Sven Barth wrote: > That won't help with Halt() however as that will "jump" directly to the > unit finalization, ignoring any and all exception handlers along the way. Wow, that's a bit harsh. Overriding the whole meaning of the try..finally language feature. Then I would recommend NOT using Halt() for anything - its nasty.

I only use it in the interpreting command line parameters phase. If there is an error, I display help and halt. And probably even in this cases I shouldn't, it's a dirty hack.

Saludos Santiago A.

Reply by email

Bart
to grouchysmurf
grouchysmurf wrote
> Probably you can set system.ExitCode before calling Terminate. I ended up doing exactly that though it feels like an ugly thoug incomplete hack. Thanks for the tip.

Why a hack?
System.ExitCode is meant for returning exitcodes.
an overloaded TCustomApplication.Terminate(AExitCode: Integer) might be nice to have though.

You could file it as a feature request in the bigtracker.

Bart

Reply by email

grouchysmurf
to Bart

Hi.

Show quoted text 5 lines
> I ended up doing exactly that though it feels like an ugly thoug[h] > incomplete hack. Thanks for the tip. Why a hack? System.ExitCode is meant for returning exitcodes.

Being forced to forfeit one or two layers of abstraction in an object oriented environment does sound like a hack to me. A direct access to system variables is inelegant to my unexperienced eye but YMMV.

Łukasz

Reply by email

Bart
to grouchysmurf
grouchysmurf wrote 6 lines
> Why a hack? > System.ExitCode is meant for returning exitcodes. Being forced to forfeit one or two layers of abstraction in an object oriented environment does sound like a hack to me. A direct access to system variables is inelegant to my unexperienced eye but YMMV.

I can see your reasoning.
Again: file a feature request (with the above argumentation) in the bugtracker. Attach a patch, this will increase the likelyhood it'll be looked into by one of the devels.

Bart

Reply by email

Lars
to grouchysmurf: Hi. Being forced to forfeit one or two layers of abstraction in an object oriented…
grouchysmurf wrote 14 lines
Hi. >> I ended up doing exactly that though it feels like an ugly thoug[h] >> incomplete hack. Thanks for the tip. > Why a hack? > System.ExitCode is meant for returning exitcodes. > Being forced to forfeit one or two layers of abstraction in an object oriented environment does sound like a hack to me. A direct access to system variables is inelegant to my unexperienced eye but YMMV.

Wasn't MSEIDE by Martin dealing with exit codes in a different way? been a logn time since I used it but I recalled something about exit codes in it. If it is an OOP architecture (msegui) how does he deal with it? Sorry this is a little off topic but, different tools deal with things in different ways and sometimes it is nice to learn from the neighboring tool to see what elegant solutions they came up with.

Reply by email