Re: [fpc-devel] heaptrc: question about missing caller stack
Part of the mystery here could be that the compiler is optimizing out the stack frame on the actual AllocMem call (which is compiled when making the compiler). It seems that recompiling after placing {$OPTIMIZATION OFF} before GetMem in rtl/inc/heap.inc [and {$OPTIMIZATION DEFAULT} after ReallocMemory] ensures the compiler generates a stack frame for these calls. However, it is still necessary either 1) to edit heaptrc.pp to call CaptureBacktrace with skipframes=0 or 2) to change the CaptureBacktrace function not to discard a stackframe (as shown in the original post). After these modifications, heap.trc shows the expected information. -JT From: jtm_1...@hotmail.com To: fpc-devel@lists.freepascal.org Date: Mon, 28 Apr 2014 18:26:59 -0500 Subject: [fpc-devel] heaptrc: question about missing caller stack [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 (iprev_frame) and (curr_frame=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:\Developm
Re: [fpc-devel] Heaptrc settings by environments
On 22/04/2014 08:12, Michael Van Canneyt wrote: On Mon, 21 Apr 2014, Martin Frb wrote: About: tracesize = 8; This is currently used in type definition theap_mem_info = record calls: array [1..tracesize] of codepointer; So it can not be changed at runtime. Without any intend of immediate action, but curiosity for future potential patches, would it be considered acceptable, if: - The array was moved to the end of record, and defined calls: array [1..8] of codepointer; I would make this array[1..1] of codepointer. Was my first thought. Then I reflected that the record should be dividable by 8 bytes. Though I overdone it, 1..2 (for 32 bit) would do that.) Of course not really needed either, since the memory boundary will anyway be adjusted when the variable length is added. But (without range check) would allow arbitrary indexes - All memory alloc would replace "sizeof(theap_mem_info)" by "sizeof(theap_mem_info)+(tracesize-8)*sizeof(codepointer)" (can be pre calculated) - checks where in place to ensure it is divide-able by 8 / minimum of 8 - all resulting errors and problems (potentially a great many) would be fixed. Allowing to make the value configurable. I want this feature since a long time since the default is ridiculously small. I didn't think of putting it at the end of the block, and this could indeed work. :) ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] Heaptrc settings by environments
On Mon, 21 Apr 2014, Martin Frb wrote: http://www.freepascal.org/docs-html/rtl/heaptrc/environment.html I was comparing the keywords accepted in the environment with the list of options that exist in the unit. The following can be set by env, but is not in the doc (based on 2.7.1) HaltOnNotReleased : boolean = false; Could/Should the following be added to the environment? Not sure what it actually does, but the option is implemented... { less checking } quicktrace : boolean=true; { add a small footprint at the end of memory blocks, this can check for memory overwrites at the end of a block } add_tail : boolean = true; { put crc in sig this allows to test for writing into that part } usecrc : boolean = true; printleakedblock: boolean = false; printfaultyblock: boolean = false; maxprintedblocklength: integer = 128; --- About: tracesize = 8; This is currently used in type definition theap_mem_info = record calls: array [1..tracesize] of codepointer; So it can not be changed at runtime. Without any intend of immediate action, but curiosity for future potential patches, would it be considered acceptable, if: - The array was moved to the end of record, and defined calls: array [1..8] of codepointer; I would make this array[1..1] of codepointer. But (without range check) would allow arbitrary indexes - All memory alloc would replace "sizeof(theap_mem_info)" by "sizeof(theap_mem_info)+(tracesize-8)*sizeof(codepointer)" (can be pre calculated) - checks where in place to ensure it is divide-able by 8 / minimum of 8 - all resulting errors and problems (potentially a great many) would be fixed. Allowing to make the value configurable. I want this feature since a long time since the default is ridiculously small. I didn't think of putting it at the end of the block, and this could indeed work. Michael. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Re: [fpc-devel] heaptrc
Jonas Maebe schreef: On 19 Nov 2009, at 20:42, Vincent Snijders wrote: Jonas Maebe schreef: On 19 Nov 2009, at 20:31, Vincent Snijders wrote: Nice idea, if only the bug in gdb (on windows) to set environment variables in the debuggee would be fixed... Where's the gdb bug report? I can't find it. Where should it be reported? http://sourceware.org/bugzilla/ (google: report gdb bug) How should report it? Using a reproducible case described step by step, similar to an FPC bug report. Bonus points if you can provide a C program to reproduce it. If you only have an FPC program, it's best to include also a compiled version so that people interested in looking it at don't have to install FPC first (although it's possible that Pierre will be the one looking at that report). I tried, but I am not capable of writing the c program: http://sourceware.org/bugzilla/show_bug.cgi?id=10989 Vincent ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] heaptrc
On 19 Nov 2009, at 20:42, Vincent Snijders wrote: > Jonas Maebe schreef: >> On 19 Nov 2009, at 20:31, Vincent Snijders wrote: >>> Nice idea, if only the bug in gdb (on windows) to set environment variables >>> in the debuggee would be fixed... >> Where's the gdb bug report? I can't find it. > > Where should it be reported? http://sourceware.org/bugzilla/ (google: report gdb bug) > How should report it? Using a reproducible case described step by step, similar to an FPC bug report. Bonus points if you can provide a C program to reproduce it. If you only have an FPC program, it's best to include also a compiled version so that people interested in looking it at don't have to install FPC first (although it's possible that Pierre will be the one looking at that report). Jonas___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] heaptrc
Jonas Maebe schreef: On 19 Nov 2009, at 20:31, Vincent Snijders wrote: Nice idea, if only the bug in gdb (on windows) to set environment variables in the debuggee would be fixed... Where's the gdb bug report? I can't find it. Where should it be reported? How should report it? Vincent ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] heaptrc
On 19 Nov 2009, at 20:31, Vincent Snijders wrote: > Nice idea, if only the bug in gdb (on windows) to set environment variables > in the debuggee would be fixed... Where's the gdb bug report? I can't find it. Jonas___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] heaptrc
Martin schreef: IMHO the IDE should by default set the enviromane so the heaptrc gets written to a file in the project dir (which is cleared by the IDE before). Then the IDE can pick it up... Nice idea, if only the bug in gdb (on windows) to set environment variables in the debuggee would be fixed... Vincent ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] heaptrc
Luiz Americo Pereira Camara wrote: Graeme Geldenhuys escreveu: JoshyFun wrote: (Windows only I think, and I do not know if Lazarus exclusive) Is there any way to add a cancel button to the window that show leaks ? It's not specific to Lazarus or Windows. As Vincent said, rather output to file using an environment variable. The heaptrc documentation explains it all. A better solution would be implement some kind of callback in heaptrc that could be hooked by the application to intercept and decide when and how to show. This could allow LCL applications to show e.g. a window with the leakview control instead of the std message window. If you use a hook, to put the heptrc window in place, then the whole thing would run in the user app => put an instance of the heaptrc window in the uswer app can not control the ide to jump anywhere => so no use. IMHO the IDE should by default set the enviromane so the heaptrc gets written to a file in the project dir (which is cleared by the IDE before). Then the IDE can pick it up... ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] heaptrc
Graeme Geldenhuys escreveu: JoshyFun wrote: (Windows only I think, and I do not know if Lazarus exclusive) Is there any way to add a cancel button to the window that show leaks ? It's not specific to Lazarus or Windows. As Vincent said, rather output to file using an environment variable. The heaptrc documentation explains it all. A better solution would be implement some kind of callback in heaptrc that could be hooked by the application to intercept and decide when and how to show. This could allow LCL applications to show e.g. a window with the leakview control instead of the std message window. Luiz ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] heaptrc
JoshyFun wrote: > > on each run and in the development process and test you must manually > open the file to know if something leaks (easy to forget). Under any unix-type environment do the following in a console window... Simply keep this console window open in one corner of your screen. $ tail -f eg: $ tail -f /tmp/heaptrc.txt This will now continuously show you the output of heaptrc. Alternatively, always execute your applications from the command line and simply let heaptrc output to stdout. On application exit you will get a summary output and if memory leaks occured, the need information for the leaks. Regards, - Graeme - -- fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://opensoft.homeip.net/fpgui/ ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] heaptrc
JoshyFun wrote: > > (Windows only I think, and I do not know if Lazarus exclusive) > > Is there any way to add a cancel button to the window that show leaks > ? It's not specific to Lazarus or Windows. As Vincent said, rather output to file using an environment variable. The heaptrc documentation explains it all. The 'leakview' Lazarus add-on is also a good option - I've used it a few times before. Regards, - Graeme - -- fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://opensoft.homeip.net/fpgui/ ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] heaptrc
Mattias Gaertner schreef: On Thu, 19 Nov 2009 10:53:09 +0100 JoshyFun wrote: Hello FPC, The Graeme's comment about heaptrace bring me some questions about it that were "lost in my pocket". (Windows only I think, and I do not know if Lazarus exclusive) Is there any way to only show the heaptrace window when leaks are present ? Is there any way to add a cancel button to the window that show leaks ? With 1000 leaks is not funny to press the OK button around 300 times. I know I can cancel the program, but a cancel button seems to be more clean. I guess these are todos. I am not so sure. Heaptrc outputs to stdout. If the application is compiled -WG the RTL redirects the output to message windows. I would recommend to let heatprc write to file. See http://www.freepascal.org/docs-html/rtl/heaptrc/environment.html and/or http://www.freepascal.org/docs-html/rtl/heaptrc/setheaptraceoutput.html If this message is more a Lazarus related problem, please let me know. Thank you. Yes, it is more lazarus related. I disagree. Any GUI application with heaptrace has the same issue. OTOH, if the output is redirected to file, Lazarus has a nice view: leakview, a ide plug-in you can find in lazarus\components\leakview Vincent ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] heaptrc
On Thu, 19 Nov 2009 10:53:09 +0100 JoshyFun wrote: > Hello FPC, > > The Graeme's comment about heaptrace bring me some questions about it > that were "lost in my pocket". > > (Windows only I think, and I do not know if Lazarus exclusive) > > Is there any way to only show the heaptrace window when leaks are > present ? > Is there any way to add a cancel button to the window that show leaks > ? > > With 1000 leaks is not funny to press the OK button around 300 times. > I know I can cancel the program, but a cancel button seems to be more > clean. I guess these are todos. > If this message is more a Lazarus related problem, please let me know. > Thank you. Yes, it is more lazarus related. Mattias ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel]heaptrc: web bug 2632
> >I added an extra local variable to hold the previous bp and the loop now > >looks like this: > > bp:=get_caller_frame(get_frame); > > for i:=1 to tracesize do > >begin > > pheap_mem_info(p)^.calls[i]:=get_caller_addr(bp); > > oldbp := bp; > > bp:=get_caller_frame(bp); > > if (bp >bp:= 0; > >end; > > > >I recompiled the rtl and run several test programs and the programs > >didn't crash anymore. > >The check on the frame pointer could be more sophisticated if I knew a > >way to find out what the top of the stack is, so I could check if the > >frame pointer is in stack. > > Thanks, i've applied the patch Peter: We could save the initial stackptr in the initcode? ___ fpc-devel maillist - [EMAIL PROTECTED] http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel]heaptrc: web bug 2632
I added an extra local variable to hold the previous bp and the loop now looks like this: bp:=get_caller_frame(get_frame); for i:=1 to tracesize do begin pheap_mem_info(p)^.calls[i]:=get_caller_addr(bp); oldbp := bp; bp:=get_caller_frame(bp); if (bp I recompiled the rtl and run several test programs and the programs didn't crash anymore. The check on the frame pointer could be more sophisticated if I knew a way to find out what the top of the stack is, so I could check if the frame pointer is in stack. Thanks, i've applied the patch Peter ___ fpc-devel maillist - [EMAIL PROTECTED] http://lists.freepascal.org/mailman/listinfo/fpc-devel