[fpc-devel] heaptrc: question about missing caller stack
J S
jtm_1986 at hotmail.com
Tue Apr 29 01:26:59 CEST 2014
[Sorry for the length and clutter of this post.]
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.)
I've created a small test program:
{Test program "HeaptrcTest" ******************************************************}
{*********************************************************************************}
program HeaptrcTest;
uses SysUtils;
function MyCaptureBacktrace(skipframes,count:sizeint;frames:PCodePointer):sizeint;
var
curr_frame,prev_frame: pointer;
curr_addr: codepointer;
i: sizeint;
begin
curr_frame:=get_frame;
curr_addr:=get_pc_addr;
prev_frame:=curr_frame;
{ *** Leave the following line in to advance past the call to this function *** }
get_caller_stackinfo(curr_frame,curr_addr);
i:=-skipframes;
while (i<count) and (curr_frame>prev_frame) and
(curr_frame<StackTop) do
begin
prev_frame:=curr_frame;
{ *** Do not call here so that the current caller stack gets reported *** }
// get_caller_stackinfo(curr_frame,curr_addr); // moved
if (curr_addr=nil) or
(curr_frame=nil) then
break;
if (i>=0) then
frames[i]:=curr_addr;
inc(i);
{ *** Moved the line from above to end of loop *** }
get_caller_stackinfo(curr_frame,curr_addr); // moved here
end;
if i<0 then
result:=0
else
result:=i;
end;
procedure TestAllocSecond;
var CodeArray: array[0..101] of codepointer;
Frames: Integer;
ii: Integer;
begin
AllocMem(1024);
WriteLn('');
WriteLn('***** CaptureBacktrace from AllocMem point *****');
Frames := CaptureBacktrace(0, Length(CodeArray), @CodeArray[0]);
for ii := 0 to Frames - 1 do
WriteLn(BackTraceStrFunc(CodeArray[ii]));
WriteLn('');
WriteLn('');
WriteLn('***** MyCaptureBacktrace from AllocMem point *****');
Frames := MyCaptureBacktrace(0, Length(CodeArray), @CodeArray[0]);
for ii := 0 to Frames - 1 do
WriteLn(BackTraceStrFunc(CodeArray[ii]));
end;
procedure TestAllocFirst;
begin
TestAllocSecond;
end;
begin
if FileExists('heap.trc') then
DeleteFile('heap.trc');
SetHeapTraceOutput('heap.trc');
TestAllocFirst;
end.
{*********************************************************************************}
{Output from program "HeaptrcTest" FPC SVN revision 27676 ************************}
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:
C:\DevelopmentEnvironment\Projects\TempProjects\Heaptrc Test>heaptrctest
***** CaptureBacktrace from AllocMem point *****
$00401828 TESTALLOCFIRST, line 62 of HeaptrcTest.lpr
$0040185F main, line 70 of HeaptrcTest.lpr
***** MyCaptureBacktrace from AllocMem point *****
$004017A2 TESTALLOCSECOND, line 55 of HeaptrcTest.lpr
$00401828 TESTALLOCFIRST, line 62 of HeaptrcTest.lpr
$0040185F main, line 70 of HeaptrcTest.lpr
and heap.trc is:
C:\DevelopmentEnvironment\Projects\TempProjects\Heaptrc Test\HeaptrcTest.exe
Heap dump by heaptrc unit
63 memory blocks allocated : 3471/3648
62 memory blocks freed : 2447/2624
1 unfreed memory blocks : 1024
True heap size : 458752 (144 used in System startup)
True free heap : 457504
Should be : 457520
Call trace for block $00312110 size 1024
$0040185F main, line 70 of HeaptrcTest.lpr
The output from MyCaptureBacktrace is closest to what is needed. The output from heaptrc is of little help.
{*********************************************************************************}
{Output from program "HeaptrcTest" FPC modified from SVN revision 27676 **********}
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:
C:\DevelopmentEnvironment\Projects\TempProjects\Heaptrc Test>heaptrctest
***** CaptureBacktrace from AllocMem point *****
$0040169D TESTALLOCSECOND, line 47 of HeaptrcTest.lpr
$00401828 TESTALLOCFIRST, line 62 of HeaptrcTest.lpr
$0040185F main, line 70 of HeaptrcTest.lpr
***** MyCaptureBacktrace from AllocMem point *****
$004017A2 TESTALLOCSECOND, line 55 of HeaptrcTest.lpr
$00401828 TESTALLOCFIRST, line 62 of HeaptrcTest.lpr
$0040185F main, line 70 of HeaptrcTest.lpr
and heap.trc is:
C:\DevelopmentEnvironment\Projects\TempProjects\Heaptrc Test\HeaptrcTest.exe
Heap dump by heaptrc unit
65 memory blocks allocated : 3714/3904
64 memory blocks freed : 2690/2880
1 unfreed memory blocks : 1024
True heap size : 458752 (144 used in System startup)
True free heap : 457504
Should be : 457520
Call trace for block $01612110 size 1024
$0040DE94
$00401828 TESTALLOCFIRST, line 62 of HeaptrcTest.lpr
$0040185F main, line 70 of HeaptrcTest.lpr
This is closer, but still has some noise in the heaptrc output.
{*********************************************************************************}
{Question*************************************************************************}
After modifying CaptureBacktrace, why is there a difference in the heap.trc output compared to the CaptureBacktrace called from the program?
Thanks for your insight,
-JT
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freepascal.org/pipermail/fpc-devel/attachments/20140428/ccf89929/attachment.html>
More information about the fpc-devel
mailing list