Recent

Author Topic: Getting output from heaptrc  (Read 446 times)

daivid

  • New member
  • *
  • Posts: 5
Getting output from heaptrc
« on: August 15, 2019, 04:20:05 pm »
My program keeps crashing and when I use the debuger it is clear why because at that point an object is being read which is filled with random data even though at an earlier point it contained valid data. Hence I suspect memory corruption most likely some memory has been freed that shouldn't have been.

Under Projec, Options , Compiler Options, Debugging I have ticked the box for heaptrc.

In the lpr file I've added:

{$DEFINE debug}   
+
  {$IFDEF debug}
  , SysUtils
  {$ENDIF}


  {$IFDEF DEBUG}
  // Assuming your build mode sets -dDEBUG in Project Options/Other when defining -gh
  // This avoids interference when running a production/default build without -gh

  // Set up -gh output for the Leakview package:
  if FileExists('heap.trc') then
    DeleteFile('heap.trc');
  SetHeapTraceOutput('heap.trc');
  {$ENDIF DEBUG}

but when I run my program and it crashes all the heap.trc contains is this:

<path to program>/akon
No heap dump by heaptrc unit
Exitcode = 210

I assume there is some step in setting up heap.trc that I've missed out. Any pointers?

Lazarus version 1.6.2+dfsg-2
FPC Version 3.0.0
OS Debian linux


Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 5633
    • wiki
Re: Getting output from heaptrc
« Reply #1 on: August 15, 2019, 06:09:17 pm »
heaptrc only reports leaks. That is memory that does not get freed by your app. Heaptrc cannot know when you are planing to free it. So what it does is, it waits to the very end of your app, and reports any mem that is not freed by then.

But I see you are on linux. There is a great tool for detecting mem corruption: valgrind

Install valgrind

Configure your app to use CMEM.
Compile with dwarf2 (with sets)
If need also apply dwarf to packages.

Outside the IDE (from memory / hope this is correct)
valgrind --tool=memcheck ./project1

This will give plenty output.
- Some leaks in gtk
- Read 1 to 8 bytes outside a block..... (That can sometimes be ok)

You are looking for writing outside a block, or writing to freed memory, or reading from freed memory...

You should be able to import valgrinds output into the IDE leak-view.
« Last Edit: August 15, 2019, 06:16:00 pm by Martin_fr »

Thaddy

  • Hero Member
  • *****
  • Posts: 8927
Re: Getting output from heaptrc
« Reply #2 on: August 15, 2019, 06:41:24 pm »
My program keeps crashing and when I use the debuger it is clear why because at that point an object is being read which is filled with random data even though at an earlier point it contained valid data. Hence I suspect memory corruption most likely some memory has been freed that shouldn't have been.
That is use-after-free and is always a programmer mistake
Quote
Under Projec, Options , Compiler Options, Debugging I have ticked the box for heaptrc.

In the lpr file I've added:

{$DEFINE debug}   
+
  {$IFDEF debug}
  , SysUtils
  {$ENDIF}


  {$IFDEF DEBUG}
  // Assuming your build mode sets -dDEBUG in Project Options/Other when defining -gh
  // This avoids interference when running a production/default build without -gh

  // Set up -gh output for the Leakview package:
  if FileExists('heap.trc') then
    DeleteFile('heap.trc');
  SetHeapTraceOutput('heap.trc');
  {$ENDIF DEBUG}
Use -glh or select also the include line numbers option in Lazarus.
Quote
but when I run my program and it crashes all the heap.trc contains is this:

<path to program>/akon
No heap dump by heaptrc unit
Exitcode = 210
That means the object is not initialized: did you create it? and did you use FreeAndNil?
Using FreeAndNil hides the bug, which makes it a lot more difficult to debug. But the bug is still caught. Only possibly too late.
Did you check all warnings the compiler gave you? That will fix your bug.
Quote
I assume there is some step in setting up heap.trc that I've missed out. Any pointers?

Lazarus version 1.6.2+dfsg-2
FPC Version 3.0.0
OS Debian linux
No. there's a bigger bug in your code than heaptrc can find:
1. Either the instance is not created at all
2  Or it was released too soon and you used FreeAndNil, so now you can't find the exact spot.......
« Last Edit: August 15, 2019, 06:54:02 pm by Thaddy »
Most people that want to use threading should learn to patch their jeans first: use a needle.

Thaddy

  • Hero Member
  • *****
  • Posts: 8927
Re: Getting output from heaptrc
« Reply #3 on: August 15, 2019, 07:04:21 pm »
The problem with FreeAndNil is in this case as I described, but do not ignore warnings.
Although these can range from close to errors to close to hints they should be fixed.
I suspect you have plenty of warnings in your code.. fix them.
« Last Edit: August 15, 2019, 07:05:52 pm by Thaddy »
Most people that want to use threading should learn to patch their jeans first: use a needle.

daivid

  • New member
  • *
  • Posts: 5
Re: Getting output from heaptrc
« Reply #4 on: August 15, 2019, 09:26:30 pm »
Thanks to both of you for explaining how heaptrc is not where I should be looking for clues to what is causing the the memory corruption.

This will give plenty output.

Valgrind does indeed give plenty of output- overwhelming even.

- Some leaks in gtk
- Read 1 to 8 bytes outside a block..... (That can sometimes be ok)
When you say leaks in gtk, do you mean that gtk will throw up some false positives that I need to ignore to focus on the errors caused by my code?

That is use-after-free and is always a programmer mistake
I never doubted it.


That means the object is not initialized: did you create it? and did you use FreeAndNil?
Using FreeAndNil hides the bug, which makes it a lot more difficult to debug. But the bug is still caught. Only possibly too late.
Did you check all warnings the compiler gave you? That will fix your bug.
I googled FreeAndNil  and that seems to be a procedure I don't use but I do sometimes set objects to nil "just in case" which I now suspect may be producing a similar effect as what you describe.

Your suspicion is correct the compiler does throw up a lot of warnings and while most do seem to be benign it does mean that anything serious will get lost in the crowd so I guess fixing those needs to be my first task.

Thanks again to both of you.

Thaddy

  • Hero Member
  • *****
  • Posts: 8927
Re: Getting output from heaptrc
« Reply #5 on: August 15, 2019, 09:58:35 pm »
I googled FreeAndNil  and that seems to be a procedure I don't use but I do sometimes set objects to nil "just in case" which I now suspect may be producing a similar effect as what you describe.
Yes in your case it has a similar effect. I will add a link from Danny Thorpe later (a former  Delphi team lead /scientist) for a detailed explanation.
https://blog.therealoracleatdelphi.com/2010/02/a-case-when-freeandnil-is-your-enemy_16.html

It explains in detail when and when not to set something, anything, to nil: think first. That single blog post is the ultimate guide. (Also read the previous post!!! in that post!)

I am glad you do not ignore warnings.
« Last Edit: August 15, 2019, 10:09:08 pm by Thaddy »
Most people that want to use threading should learn to patch their jeans first: use a needle.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 5633
    • wiki
Re: Getting output from heaptrc
« Reply #6 on: August 15, 2019, 10:55:09 pm »
- Some leaks in gtk
- Read 1 to 8 bytes outside a block..... (That can sometimes be ok)
When you say leaks in gtk, do you mean that gtk will throw up some false positives that I need to ignore to focus on the errors caused by my code?

Your crash, and the leaks are not related.

A leak is memory that is never freed. Other than running out of memory, it will not cause crashes.
You are writing to "the wrong mem" (either never allocated, freed, or cross boundaries (enable range checks!)).

valgrind reports both.

As for the "gtk leaks" I do not know if they are in gtk or lcl. But I know you get a lot of reports.

You are looking for errors like
Code: Text  [Select]
  1. ==23779== Invalid write of size 4
  2. ==23779==  Address 0x4c30068 is 0 bytes after a block of size 40 alloc'd

or the memory is part of a block that was freed.
You will get traces
- where the error happened,
- where the memory was allocated
- and where it was freed (in case of)

You may also have read errors that are relevant. Reading from a block that was freed could cause crashes too.

Reading just 1 to 3 bytes extra could be something the compiler added, and that will do no harm.
I.e. if you read a single byte from memory that was allocated as 1 byte only, the cpu may read a full integer, and then use only the byte. But valgrind will report it. (as it technically is out of bounds)

But reading more than 3 bytes behind the block, may indicate a real error.


There may be an option (not sure) to suppress the leak reports, since you do not need them (well not to find the crash)

Thaddy

  • Hero Member
  • *****
  • Posts: 8927
Re: Getting output from heaptrc
« Reply #7 on: August 16, 2019, 07:25:05 am »
It would help if you are able to obtain a stack trace too. I am almost sure it is use after free.
Most people that want to use threading should learn to patch their jeans first: use a needle.

BrunoK

  • Full Member
  • ***
  • Posts: 181
  • Retired programmer
Re: Getting output from heaptrc
« Reply #8 on: August 16, 2019, 11:47:32 am »
@daivid

Do you use AllocMem in you program with heaptrc.

If yes, there is a bug in standard heaptrc,
Code: Pascal  [Select]
  1. function TraceAllocMem(size:ptruint):Pointer;
  2. begin
  3.   TraceAllocMem:=SysAllocMem(size);
  4. end;
  5.  

Does not handle correctly the trace structures so when you FreeMem a block allocated with  AllocMem, the  internal structure of heaptrc might be damaged.
Lazarus trunk r. 59978/03.01.2019 (+/- patches regarding enabled, TScrollBar, TCursorImage). FPC 3.0.4 32 bits. (+heaptrc with leaked ClassName+Revisited TList) , Windows 10 Pro x64 (v. 1903)