From 0cc53cc5dfdb768981953ee4ebef543608aa0c4b Mon Sep 17 00:00:00 2001 From: florian <florian@freepascal.org> Date: Tue, 16 Aug 2011 20:47:15 +0000 Subject: [PATCH] + patch from Benito van der Zander to enable heaptrc to dump leaked or faulty memory blocks (function disabled by default), resolves #19691 git-svn-id: trunk@18231 - --- rtl/inc/heaptrc.pp | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/rtl/inc/heaptrc.pp b/rtl/inc/heaptrc.pp index b84aec1ae6..12168d13d8 100644 --- a/rtl/inc/heaptrc.pp +++ b/rtl/inc/heaptrc.pp @@ -80,6 +80,9 @@ const this allows to test for writing into that part } usecrc : boolean = true; + printleakedblock: boolean = false; + printfaultyblock: boolean = false; + maxprintedblocklength: integer = 128; implementation @@ -255,14 +258,50 @@ function InternalFreeMemSize(loc_info: pheap_info; p: pointer; pp: pheap_mem_inf size: ptruint; release_todo_lock: boolean): ptruint; forward; function TraceFreeMem(p: pointer): ptruint; forward; +procedure printhex(p : pointer; const size : PtrUInt; var ptext : text); +var s: PtrUInt; + i: Integer; +begin + s := size; + if s > maxprintedblocklength then + s := maxprintedblocklength; + + for i:=0 to s-1 do + write(ptext, hexstr(pbyte(p + i)^,2)); + + if size > maxprintedblocklength then + writeln(ptext,'.. - ') + else + writeln(ptext, ' - '); + + for i:=0 to s-1 do + if pchar(p + sizeof(theap_mem_info) + i)^ < ' ' then + write(ptext, ' ') + else + write(ptext, pchar(p + i)^); + + if size > maxprintedblocklength then + writeln(ptext,'..') + else + writeln(ptext); +end; + procedure call_stack(pp : pheap_mem_info;var ptext : text); var i : ptruint; + s: PtrUInt; begin writeln(ptext,'Call trace for block $',hexstr(pointer(pp)+sizeof(theap_mem_info)),' size ',pp^.size); + if printleakedblock then + begin + write(ptext, 'Block content: '); + printhex(pointer(pp) + sizeof(theap_mem_info), pp^.size, ptext); + end; + for i:=1 to tracesize do if pp^.calls[i]<>nil then writeln(ptext,BackTraceStrFunc(pp^.calls[i])); + { the check is done to be sure that the procvar is not overwritten } if assigned(pp^.extra_info) and (pp^.extra_info^.check=$12345678) and @@ -303,6 +342,11 @@ procedure dump_error(p : pheap_mem_info;var ptext : text); begin Writeln(ptext,'Marked memory at $',HexStr(pointer(p)+sizeof(theap_mem_info)),' invalid'); Writeln(ptext,'Wrong signature $',hexstr(p^.sig,8),' instead of ',hexstr(calculate_sig(p),8)); + if printfaultyblock then + begin + write(ptext, 'Block content: '); + printhex(pointer(p) + sizeof(theap_mem_info), p^.size, ptext); + end; dump_stack(ptext,get_caller_frame(get_frame)); end;