Generic way to pre-maturely exit TCustomApplication without memory leaks

classic Classic list List threaded Threaded
17 messages Options
Reply | Threaded
Open this post in threaded view
|

Generic way to pre-maturely exit TCustomApplication without memory leaks

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

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Generic way to pre-maturely exit TCustomApplication without memory leaks

Michael Van Canneyt


On Wed, 12 Oct 2016, grouchysmurf wrote:

> 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.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Generic way to pre-maturely exit TCustomApplication without memory leaks

Graeme Geldenhuys-6
In reply to this post by grouchysmurf
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;



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
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Generic way to pre-maturely exit TCustomApplication without memory leaks

Bart-48
In reply to this post by Michael Van Canneyt
On 10/13/16, Michael Van Canneyt <[hidden email]> 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
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Generic way to pre-maturely exit TCustomApplication without memory leaks

Santiago A.
In reply to this post by Graeme Geldenhuys-6
El 13/10/2016 a las 10:09, Graeme Geldenhuys escribió:
> 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.

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Generic way to pre-maturely exit TCustomApplication without memory leaks

Sven Barth-2
In reply to this post by Graeme Geldenhuys-6

Am 13.10.2016 10:09 schrieb "Graeme Geldenhuys" <[hidden email]>:
>
> 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


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Generic way to pre-maturely exit TCustomApplication without memory leaks

Graeme Geldenhuys-6
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.


Regards,
  Graeme

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Generic way to pre-maturely exit TCustomApplication without memory leaks

Sven Barth-2

Am 13.10.2016 15:07 schrieb "Graeme Geldenhuys" <[hidden email]>:
>
> 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.
>

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


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Generic way to pre-maturely exit TCustomApplication without memory leaks

grouchysmurf
In reply to this post by Michael Van Canneyt
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

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Generic way to pre-maturely exit TCustomApplication without memory leaks

grouchysmurf
In reply to this post by Graeme Geldenhuys-6
Hi.

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

Thanks.  This  is what I am planning to do eventually but as for now I
am  learning  the  ropes  --  freepascal is kind of new to me and I am
slowly learning its new features. Last Pascal I've been programming in
was TP 6.0 with TurboVision.

Oh, the memories...

Łukasz

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Generic way to pre-maturely exit TCustomApplication without memory leaks

grouchysmurf
In reply to this post by Santiago A.
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

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Generic way to pre-maturely exit TCustomApplication without memory leaks

Santiago A.
In reply to this post by Graeme Geldenhuys-6
El 13/10/2016 a las 15:07, Graeme Geldenhuys escribió:
> 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.

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Generic way to pre-maturely exit TCustomApplication without memory leaks

grouchysmurf
In reply to this post by Bart-48
> 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.

Łukasz

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Generic way to pre-maturely exit TCustomApplication without memory leaks

Bart-48
On 10/16/16, grouchysmurf <[hidden email]> 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
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Generic way to pre-maturely exit TCustomApplication without memory leaks

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

Łukasz

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Generic way to pre-maturely exit TCustomApplication without memory leaks

Bart-48
On 10/17/16, grouchysmurf <[hidden email]> wrote:

>> 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
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Generic way to pre-maturely exit TCustomApplication without memory leaks

noreply
In reply to this post by grouchysmurf
On Mon, October 17, 2016 12:18 am, grouchysmurf wrote:

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


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal