<html>
<head>
<style><!--
.hmmessage P
{
margin:0px;
padding:0px
}
body.hmmessage
{
font-size: 12pt;
font-family:Calibri
}
--></style></head>
<body class='hmmessage'><div dir='ltr'>[Sorry for the length and clutter of this post.]<br><br>It is really helpful when tracking down memory leaks to have a call stack that goes all the way to the line where the memory is allocated. Currently, heaptrc does not do this entirely. (At least on my system.)<br><br>I've created a small test program:<br><br>{Test program "HeaptrcTest" ******************************************************}<br>{*********************************************************************************}<br>program HeaptrcTest;<br>uses SysUtils;<br><br>function MyCaptureBacktrace(skipframes,count:sizeint;frames:PCodePointer):sizeint; <br>var<br>  curr_frame,prev_frame: pointer;<br>  curr_addr: codepointer;<br>  i: sizeint;<br>begin<br>  curr_frame:=get_frame;<br>  curr_addr:=get_pc_addr;<br>  prev_frame:=curr_frame;<br>  { *** Leave the following line in to advance past the call to this function *** }<br>  get_caller_stackinfo(curr_frame,curr_addr);<br>  i:=-skipframes;<br>  while (i<count) and (curr_frame>prev_frame) and<br>     (curr_frame<StackTop) do<br>    begin<br>      prev_frame:=curr_frame;<br>  { *** Do not call here so that the current caller stack gets reported *** }<br>//      get_caller_stackinfo(curr_frame,curr_addr); // moved<br>      if (curr_addr=nil) or<br>         (curr_frame=nil) then<br>        break;<br>      if (i>=0) then<br>        frames[i]:=curr_addr;<br>      inc(i);<br>  { *** Moved the line from above to end of loop *** }<br>      get_caller_stackinfo(curr_frame,curr_addr);  // moved here<br>    end;<br>  if i<0 then<br>    result:=0<br>  else<br>    result:=i;<br>end;<br><br><br>procedure TestAllocSecond;<br>var CodeArray: array[0..101] of codepointer;<br>    Frames: Integer;<br>    ii: Integer;<br>begin<br>  AllocMem(1024);<br><br>  WriteLn('');<br>  WriteLn('***** CaptureBacktrace from AllocMem point *****');<br>  Frames := CaptureBacktrace(0, Length(CodeArray), @CodeArray[0]);<br>  for ii := 0 to Frames - 1 do<br>    WriteLn(BackTraceStrFunc(CodeArray[ii]));<br><br>  WriteLn('');<br>  WriteLn('');<br>  WriteLn('***** MyCaptureBacktrace from AllocMem point *****');<br>  Frames := MyCaptureBacktrace(0, Length(CodeArray), @CodeArray[0]);<br>  for ii := 0 to Frames - 1 do<br>    WriteLn(BackTraceStrFunc(CodeArray[ii]));<br>end;<br><br>procedure TestAllocFirst;<br>begin<br>  TestAllocSecond;<br>end;<br><br>begin<br>  if FileExists('heap.trc') then<br>    DeleteFile('heap.trc');<br>  SetHeapTraceOutput('heap.trc');<br><br>  TestAllocFirst;<br>end.<br>{*********************************************************************************}<br>{Output from program "HeaptrcTest" FPC SVN revision 27676 ************************}<br><br><br>When I run this program with FPC from SVN revision 27676 with the options "-MObjFPC -Scghi -O1 -g -gl -gh -vewnhi -Filib\i386-win32 -Fu. -FUlib\i386-win32 -l", I get the following output:<br><br>C:\DevelopmentEnvironment\Projects\TempProjects\Heaptrc Test>heaptrctest<br><br>***** CaptureBacktrace from AllocMem point *****<br>  $00401828  TESTALLOCFIRST,  line 62 of HeaptrcTest.lpr<br>  $0040185F  main,  line 70 of HeaptrcTest.lpr<br><br><br>***** MyCaptureBacktrace from AllocMem point *****<br>  $004017A2  TESTALLOCSECOND,  line 55 of HeaptrcTest.lpr<br>  $00401828  TESTALLOCFIRST,  line 62 of HeaptrcTest.lpr<br>  $0040185F  main,  line 70 of HeaptrcTest.lpr<br>  <br>and heap.trc is:<br><br>C:\DevelopmentEnvironment\Projects\TempProjects\Heaptrc Test\HeaptrcTest.exe <br>Heap dump by heaptrc unit<br>63 memory blocks allocated : 3471/3648<br>62 memory blocks freed     : 2447/2624<br>1 unfreed memory blocks : 1024<br>True heap size : 458752 (144 used in System startup)<br>True free heap : 457504<br>Should be : 457520<br>Call trace for block $00312110 size 1024<br>  $0040185F  main,  line 70 of HeaptrcTest.lpr<br><br>The output from MyCaptureBacktrace is closest to what is needed. The output from heaptrc is of little help.<br>  <br>{*********************************************************************************}<br>{Output from program "HeaptrcTest" FPC modified from SVN revision 27676 **********}<br><br>When I change heaptrc.pp to call CaptureBacktrace with a 0 in the first parameter, and then change CaptureBacktrace to match my edits, I get the following output:<br><br>C:\DevelopmentEnvironment\Projects\TempProjects\Heaptrc Test>heaptrctest<br><br>***** CaptureBacktrace from AllocMem point *****<br>  $0040169D  TESTALLOCSECOND,  line 47 of HeaptrcTest.lpr<br>  $00401828  TESTALLOCFIRST,  line 62 of HeaptrcTest.lpr<br>  $0040185F  main,  line 70 of HeaptrcTest.lpr<br><br><br>***** MyCaptureBacktrace from AllocMem point *****<br>  $004017A2  TESTALLOCSECOND,  line 55 of HeaptrcTest.lpr<br>  $00401828  TESTALLOCFIRST,  line 62 of HeaptrcTest.lpr<br>  $0040185F  main,  line 70 of HeaptrcTest.lpr<br>  <br>and heap.trc is:<br><br>C:\DevelopmentEnvironment\Projects\TempProjects\Heaptrc Test\HeaptrcTest.exe <br>Heap dump by heaptrc unit<br>65 memory blocks allocated : 3714/3904<br>64 memory blocks freed     : 2690/2880<br>1 unfreed memory blocks : 1024<br>True heap size : 458752 (144 used in System startup)<br>True free heap : 457504<br>Should be : 457520<br>Call trace for block $01612110 size 1024<br>  $0040DE94<br>  $00401828  TESTALLOCFIRST,  line 62 of HeaptrcTest.lpr<br>  $0040185F  main,  line 70 of HeaptrcTest.lpr<br><br><br>This is closer, but still has some noise in the heaptrc output.<br><br>{*********************************************************************************}<br>{Question*************************************************************************}<br><br>After modifying CaptureBacktrace, why is there a difference in the heap.trc output compared to the CaptureBacktrace called from the program?<br><br>Thanks for your insight,<br>-JT                                           </div></body>
</html>