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