[Lazarus] Is this a bug?

classic Classic list List threaded Threaded
14 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[Lazarus] Is this a bug?

Free Pascal - Lazarus mailing list
The following program produces these two memory leaks:

Heap dump by heaptrc unit
2 memory blocks allocated : 188/208
0 memory blocks freed     : 134/144
2 unfreed memory blocks : 54
True heap size : 32768
True free heap : 32320
Should be : 32448
Call trace for block $00007FFFF7FF31A0 size 27
Call trace for block $00007FFFF7FF30C0 size 27

If the call to "halt;" is commented out, there is no memory leak
reported. Is this intentional?

program TestBed;

begin
   {run the program with this run parameter: FileToLoad -v -t -r=0.0001}
   write(ParamCount,'  ');
   write(Sizeof(ParamStr(0)),'  ');
   write(Length(ParamStr(0)),'  ');
   writeln(ParamStr(0));

   write(Sizeof(ParamStr(1)),'  ');
   write(Length(ParamStr(1)),'  ');
   writeln(ParamStr(1));

   write(Sizeof(ParamStr(2)),'  ');
   write(Length(ParamStr(2)),'  ');
   writeln(ParamStr(2));

   write(Sizeof(ParamStr(3)),'  ');
   write(Length(ParamStr(3)),'  ');
   writeln(ParamStr(3));

  halt;     // terminating with "halt" causes memory leaks
  end.      // no memory leak

The size of the unfreed memory blocks varies, if the one or the other of
the program blocks are commented out. There is no discernible
correlation (to me, at least) between them and the data they are
supposed to store. Also, the total number of memory blocks allocated and
later freed varies, the record observed so far is 11 blocks allocated.
This apparently varies whenever my system is rebooted, and appears to
have something to do with what else I am running / have been running.

System: Kubuntu 16.4, Lazarus 1.6+dfsg-1 dated 2016-03-01, FPC 3.0.0

wolf


--
_______________________________________________
Lazarus mailing list
[hidden email]
http://lists.lazarus-ide.org/listinfo/lazarus
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [Lazarus] Is this a bug?

Free Pascal - Lazarus mailing list
On 16.06.2017 9:12, Wolf via Lazarus wrote:
> If the call to "halt;" is commented out, there is no memory leak
> reported. Is this intentional?

Yes, halt kills the program without finalizing anything. No code is
executed afterwards. Everything that is allocated at the time Halt is
executed results in a memory leak.

Ondrej
--
_______________________________________________
Lazarus mailing list
[hidden email]
http://lists.lazarus-ide.org/listinfo/lazarus
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [Lazarus] Is this a bug?

Free Pascal - Lazarus mailing list
In reply to this post by Free Pascal - Lazarus mailing list
On Fri, 16 Jun 2017 19:12:31 +1200
Wolf via Lazarus <[hidden email]> wrote:

> The following program produces these two memory leaks:
>
> Heap dump by heaptrc unit
> 2 memory blocks allocated : 188/208
> 0 memory blocks freed     : 134/144
> 2 unfreed memory blocks : 54
> True heap size : 32768
> True free heap : 32320
> Should be : 32448
> Call trace for block $00007FFFF7FF31A0 size 27
> Call trace for block $00007FFFF7FF30C0 size 27
>
> If the call to "halt;" is commented out, there is no memory leak
> reported. Is this intentional?

Yes.
"Halt" immediately jump to the finalization sections. That means any
try..finally sections are skipped, including the implicit frees for
the temporary strings of your example.

Mattias
--
_______________________________________________
Lazarus mailing list
[hidden email]
http://lists.lazarus-ide.org/listinfo/lazarus
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [Lazarus] Is this a bug?

Free Pascal - Lazarus mailing list
In reply to this post by Free Pascal - Lazarus mailing list
On Fri, 16 Jun 2017 09:25:24 +0200
Ondrej Pokorny via Lazarus <[hidden email]> wrote:

> On 16.06.2017 9:12, Wolf via Lazarus wrote:
> > If the call to "halt;" is commented out, there is no memory leak
> > reported. Is this intentional?  
>
> Yes, halt kills the program without finalizing anything. No code is
> executed afterwards. Everything that is allocated at the time Halt is
> executed results in a memory leak.

Halt calls the finalization sections.

Mattias
--
_______________________________________________
Lazarus mailing list
[hidden email]
http://lists.lazarus-ide.org/listinfo/lazarus
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [Lazarus] Is this a bug?

Free Pascal - Lazarus mailing list
On 16.06.2017 9:33, Mattias Gaertner via Lazarus wrote:

> On Fri, 16 Jun 2017 09:25:24 +0200
> Ondrej Pokorny via Lazarus <[hidden email]> wrote:
>
>> On 16.06.2017 9:12, Wolf via Lazarus wrote:
>>> If the call to "halt;" is commented out, there is no memory leak
>>> reported. Is this intentional?
>> Yes, halt kills the program without finalizing anything. No code is
>> executed afterwards. Everything that is allocated at the time Halt is
>> executed results in a memory leak.
> Halt calls the finalization sections.

Uppps. Thanks for the correction.

Ondrej
--
_______________________________________________
Lazarus mailing list
[hidden email]
http://lists.lazarus-ide.org/listinfo/lazarus
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [Lazarus] Is this a bug?

Free Pascal - Lazarus mailing list
In reply to this post by Free Pascal - Lazarus mailing list
Now I am nicely confused: If halt does call finalization sections, isn't
then all heap space requested by the system unit supposed to be freed as
well? I do have observed at times that some, and sometimes even all heap
space requested by the system unit, does get freed when calling halt.
So, what does this program show? Expected behavior that should not be
changed, or is it unexpected behavior that ought to be reported and changed?
wolf

On 16/06/17 19:33, Mattias Gaertner via Lazarus wrote:

> On Fri, 16 Jun 2017 09:25:24 +0200
> Ondrej Pokorny via Lazarus <[hidden email]> wrote:
>
>> On 16.06.2017 9:12, Wolf via Lazarus wrote:
>>> If the call to "halt;" is commented out, there is no memory leak
>>> reported. Is this intentional?
>> Yes, halt kills the program without finalizing anything. No code is
>> executed afterwards. Everything that is allocated at the time Halt is
>> executed results in a memory leak.
> Halt calls the finalization sections.
>
> Mattias

--
_______________________________________________
Lazarus mailing list
[hidden email]
http://lists.lazarus-ide.org/listinfo/lazarus
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [Lazarus] Is this a bug?

Free Pascal - Lazarus mailing list
On Fri, 16 Jun 2017 20:36:54 +1200
Wolf via Lazarus <[hidden email]> wrote:

> Now I am nicely confused: If halt does call finalization sections, isn't
> then all heap space requested by the system unit supposed to be freed as
> well?

The system unit is special. It is loaded even before the heap manager
is initialized. Heaptrc does not report memory of the system unit.

Heaptrc reports allocations after its initialization, which is
usually right after the system unit.


Mattias
--
_______________________________________________
Lazarus mailing list
[hidden email]
http://lists.lazarus-ide.org/listinfo/lazarus
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [Lazarus] Is this a bug?

Free Pascal - Lazarus mailing list
If I understand you correctly, because
1. command line parameters are internally treated as a null-terminated
string (i.e. AnsiString), a call to ParamStr() implies a heap allocation
and thus,
2. since ParamStr() is handled by the system unit, a call to halt will
result in a memory leak because Heaptrc is not aware of this allocation.

If this is correct, then the conclusion has to be that Heaptrc cannot be
trusted as a debugging tool because it is ill-informed about what the
system unit is up to.

wolf (rather disillusioned)

On 16/06/17 20:47, Mattias Gaertner via Lazarus wrote:

> On Fri, 16 Jun 2017 20:36:54 +1200
> Wolf via Lazarus <[hidden email]> wrote:
>
>> Now I am nicely confused: If halt does call finalization sections, isn't
>> then all heap space requested by the system unit supposed to be freed as
>> well?
> The system unit is special. It is loaded even before the heap manager
> is initialized. Heaptrc does not report memory of the system unit.
>
> Heaptrc reports allocations after its initialization, which is
> usually right after the system unit.
>
>
> Mattias

--
_______________________________________________
Lazarus mailing list
[hidden email]
http://lists.lazarus-ide.org/listinfo/lazarus
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [Lazarus] Is this a bug?

Free Pascal - Lazarus mailing list
On 06/16/2017 11:43 AM, Wolf via Lazarus wrote:
> If I understand you correctly, because
> 2. since ParamStr() is handled by the system unit, a call to halt will
> result in a memory leak because Heaptrc is not aware of this allocation.

Only the initialization of the system-unit is done before the
heap-manager is in place. So this is no issue.

The memory being allocated for the commandline and it's parameters
itself is system-specific. If there is any memory allocated at all.

> If this is correct, then the conclusion has to be that Heaptrc cannot be
> trusted as a debugging tool because it is ill-informed about what the
> system unit is up to.

Heaptrace is a great debugging-tool. Debugging-tools give you more
information to help you find problems. But they can never be trusted.
The same holds for any debugger, btw.

The part about the system-unit is incorrect. (See above)

Calling Halt(), is, well... dangerous. On the other hand you should not
care about memory-leaks on application exit. But I can imagine that it
obfuscates things when you are searching for real memory-leaks.

Try to place your code in a 'try .. finally' block, and call Halt()
thereafter. Of even better, in a procedure, and halt after the
procedure-call. You have probably problems with implicit try-finally
sections, as Mattias pointed out. You can also investigate this by
looking at the created assembly. (fpc -an)

Regards,

Joost.

> wolf (rather disillusioned)
>
> On 16/06/17 20:47, Mattias Gaertner via Lazarus wrote:
>> On Fri, 16 Jun 2017 20:36:54 +1200
>> Wolf via Lazarus <[hidden email]> wrote:
>>
>>> Now I am nicely confused: If halt does call finalization sections, isn't
>>> then all heap space requested by the system unit supposed to be freed as
>>> well?
>> The system unit is special. It is loaded even before the heap manager
>> is initialized. Heaptrc does not report memory of the system unit.
>>
>> Heaptrc reports allocations after its initialization, which is
>> usually right after the system unit.
>>
>>
>> Mattias
>

--
_______________________________________________
Lazarus mailing list
[hidden email]
http://lists.lazarus-ide.org/listinfo/lazarus
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [Lazarus] Is this a bug?

Free Pascal - Lazarus mailing list
In reply to this post by Free Pascal - Lazarus mailing list
On Fri, 16 Jun 2017 21:43:38 +1200
Wolf via Lazarus <[hidden email]> wrote:

> If I understand you correctly, because
> 1. command line parameters are internally treated as a null-terminated
> string (i.e. AnsiString), a call to ParamStr() implies a heap allocation
> and thus,
> 2. since ParamStr() is handled by the system unit, a call to halt will
> result in a memory leak because Heaptrc is not aware of this allocation.

No, that's not how temporary strings work.

Just move the code in front of your halt into a separate procedure and
the mem leaks are gone.

The compiler creates an implicit try..finally to free managed types
and since Halt skips the finally parts the strings are not freed.

 
> If this is correct, then the conclusion has to be that Heaptrc cannot be
> trusted as a debugging tool because it is ill-informed about what the
> system unit is up to.

Nonsense. This is neither specific to the system unit nor heaptrc.
The conclusion is that must not use Halt, when you need try..finally.


Mattias
--
_______________________________________________
Lazarus mailing list
[hidden email]
http://lists.lazarus-ide.org/listinfo/lazarus
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [Lazarus] Is this a bug?

Free Pascal - Lazarus mailing list
Thanks, Mattias and Joost,
now I understand the real bug is in my assumptions on what goes on
behind the screens. But that leads to another question: is there any
documentation where I can read up on this so that I may improve on my
programming, and particular debugging, skills?
wolf

On 16/06/17 23:27, Mattias Gaertner via Lazarus wrote:

> On Fri, 16 Jun 2017 21:43:38 +1200
> Wolf via Lazarus <[hidden email]> wrote:
>
>> If I understand you correctly, because
>> 1. command line parameters are internally treated as a null-terminated
>> string (i.e. AnsiString), a call to ParamStr() implies a heap allocation
>> and thus,
>> 2. since ParamStr() is handled by the system unit, a call to halt will
>> result in a memory leak because Heaptrc is not aware of this allocation.
> No, that's not how temporary strings work.
>
> Just move the code in front of your halt into a separate procedure and
> the mem leaks are gone.
>
> The compiler creates an implicit try..finally to free managed types
> and since Halt skips the finally parts the strings are not freed.
>
>  
>> If this is correct, then the conclusion has to be that Heaptrc cannot be
>> trusted as a debugging tool because it is ill-informed about what the
>> system unit is up to.
> Nonsense. This is neither specific to the system unit nor heaptrc.
> The conclusion is that must not use Halt, when you need try..finally.
>
>
> Mattias

--
_______________________________________________
Lazarus mailing list
[hidden email]
http://lists.lazarus-ide.org/listinfo/lazarus
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [Lazarus] Is this a bug?

Free Pascal - Lazarus mailing list
Op 16-06-17 om 22:58 schreef Wolf via Lazarus:
> now I understand the real bug is in my assumptions on what goes on
> behind the screens. But that leads to another question: is there any
> documentation where I can read up on this so that I may improve on my
> programming, and particular debugging, skills?

Well, it's not that this behavior is hidden. It's even documented:
https://www.freepascal.org/docs-html/ref/refch17.html.
So you could read the pure documentation....

There's also a wiki about this issue:
http://wiki.freepascal.org/Avoiding_implicit_try_finally_section

But I doubt that this is what you meant.

You asked this on the Lazarus-list, but this is more a question for the
fpc-pascal list. What you could do is follow this list, or maybe even
fpc-devel. You can also browse the archives.

You can learn a lot from there.

Regards,

Joost.


--
_______________________________________________
Lazarus mailing list
[hidden email]
http://lists.lazarus-ide.org/listinfo/lazarus
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [Lazarus] Is this a bug?

Free Pascal - Lazarus mailing list
In reply to this post by Free Pascal - Lazarus mailing list
Op 16-06-17 om 22:58 schreef Wolf via Lazarus:
> now I understand the real bug is in my assumptions on what goes on
> behind the screens. But that leads to another question: is there any
> documentation where I can read up on this so that I may improve on my
> programming, and particular debugging, skills?

Well, it's not that this behavior is hidden. It's even documented:
https://www.freepascal.org/docs-html/ref/refch17.html.
So you could read the pure documentation....

There's also a wiki about this issue:
http://wiki.freepascal.org/Avoiding_implicit_try_finally_section

But I doubt that this is what you meant.

You asked this on the Lazarus-list, but this is more a question for the
fpc-pascal list. What you could do is follow this list, or maybe even
fpc-devel. You can also browse the archives.

You can learn a lot from there.

Regards,

Joost.


--
_______________________________________________
Lazarus mailing list
[hidden email]
http://lists.lazarus-ide.org/listinfo/lazarus
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [Lazarus] Is this a bug?

Free Pascal - Lazarus mailing list
Now that I learned the word "initialization section", I could google for
it, and what's going on behind the screens is no longer murky. Thanks
again. I even found the heaptrc documentation
<https://www.freepascal.org/docs-html/rtl/heaptrc/index.html> and in it
the "dumpheap" procedure, which means I can follow heap usage throughout
my program, without any interference from "halt".
--Problem solved--.
wolf

On 18/06/17 10:07, Joost van der Sluis via Lazarus wrote:

> Op 16-06-17 om 22:58 schreef Wolf via Lazarus:
>> now I understand the real bug is in my assumptions on what goes on
>> behind the screens. But that leads to another question: is there any
>> documentation where I can read up on this so that I may improve on my
>> programming, and particular debugging, skills?
>
> Well, it's not that this behavior is hidden. It's even documented:
> https://www.freepascal.org/docs-html/ref/refch17.html.
> So you could read the pure documentation....
>
> There's also a wiki about this issue:
> http://wiki.freepascal.org/Avoiding_implicit_try_finally_section
>
> But I doubt that this is what you meant.
>
> You asked this on the Lazarus-list, but this is more a question for
> the fpc-pascal list. What you could do is follow this list, or maybe
> even fpc-devel. You can also browse the archives.
>
> You can learn a lot from there.
>
> Regards,
>
> Joost.
>
>

--
_______________________________________________
Lazarus mailing list
[hidden email]
http://lists.lazarus-ide.org/listinfo/lazarus
Loading...