diff --git a/NEWS b/NEWS index 0f78103c1..d94c4bd10 100644 --- a/NEWS +++ b/NEWS @@ -24,6 +24,10 @@ Release 3.10.0 (?? ?????? 201?) * ==================== OTHER CHANGES ==================== +* Address description logic has been improved and is now common + between memcheck and helgrind, resulting in better address + descriptions for some error messages. + * New and modified GDB server monitor features: - The GDB server monitor command 'v.info location
' diff --git a/coregrind/m_addrinfo.c b/coregrind/m_addrinfo.c index bcf691370..633933182 100644 --- a/coregrind/m_addrinfo.c +++ b/coregrind/m_addrinfo.c @@ -40,11 +40,11 @@ #include "pub_core_mallocfree.h" #include "pub_core_machine.h" #include "pub_core_options.h" +#include "pub_core_stacktrace.h" void VG_(describe_addr) ( Addr a, /*OUT*/AddrInfo* ai ) { ThreadId tid; - Addr stack_min, stack_max; VgSectKind sect; /* -- Perhaps the variable type/location data describes it? -- */ @@ -94,12 +94,45 @@ void VG_(describe_addr) ( Addr a, /*OUT*/AddrInfo* ai ) return; } /* -- Perhaps it's on a thread's stack? -- */ - VG_(thread_stack_reset_iter)(&tid); - while ( VG_(thread_stack_next)(&tid, &stack_min, &stack_max) ) { - if (stack_min - VG_STACK_REDZONE_SZB <= a && a <= stack_max) { - ai->tag = Addr_Stack; - ai->Addr.Stack.tid = tid; - return; + { + Addr stack_min, stack_max; + VG_(thread_stack_reset_iter)(&tid); + while ( VG_(thread_stack_next)(&tid, &stack_min, &stack_max) ) { + if (stack_min - VG_STACK_REDZONE_SZB <= a && a <= stack_max) { + Addr ips[VG_(clo_backtrace_size)], + sps[VG_(clo_backtrace_size)]; + UInt n_frames; + UInt f; + + ai->tag = Addr_Stack; + ai->Addr.Stack.tid = tid; + ai->Addr.Stack.IP = 0; + ai->Addr.Stack.frameNo = -1; + /* It is on thread tid stack. Build a stacktrace, and + find the frame sp[f] .. sp[f+1] where the address is. + Store the found frameNo and the corresponding IP in + the description. + When description is printed, IP will be translated to + the function name containing IP. + Before accepting to describe addr with sp[f] .. sp[f+1], + we verify the sp looks sane: reasonably sized frame, + inside the stack. + We could check the ABI required alignment for sp (what is it?) + is respected, except for the innermost stack pointer ? */ + n_frames = VG_(get_StackTrace)( tid, ips, VG_(clo_backtrace_size), + sps, NULL, 0/*first_ip_delta*/ ); + for (f = 0; f < n_frames-1; f++) { + if (sps[f] <= a && a < sps[f+1] + && sps[f+1] - sps[f] <= 0x4000000 // 64 MB, arbitrary + && sps[f+1] <= stack_max + && sps[f] >= stack_min - VG_STACK_REDZONE_SZB) { + ai->Addr.Stack.frameNo = f; + ai->Addr.Stack.IP = ips[f]; + break; + } + } + return; + } } } @@ -223,6 +256,41 @@ static void pp_addrinfo_WRK ( Addr a, AddrInfo* ai, Bool mc, Bool maybe_gcc ) case Addr_Stack: VG_(emit)( "%sAddress 0x%llx is on thread %d's stack%s\n", xpre, (ULong)a, ai->Addr.Stack.tid, xpost ); + if (ai->Addr.Stack.frameNo != -1 && ai->Addr.Stack.IP != 0) { +#define FLEN 256 + HChar fn[FLEN]; + Bool hasfn; + HChar file[FLEN]; + Bool hasfile; + UInt linenum; + Bool haslinenum; + PtrdiffT offset; + + hasfn = VG_(get_fnname)(ai->Addr.Stack.IP, fn, FLEN); + if (VG_(get_inst_offset_in_function)( ai->Addr.Stack.IP, + &offset)) + haslinenum = VG_(get_linenum) (ai->Addr.Stack.IP - offset, + &linenum); + else + haslinenum = False; + + hasfile = VG_(get_filename)(ai->Addr.Stack.IP, file, FLEN); + if (hasfile && haslinenum) { + HChar strlinenum[10]; + VG_(snprintf) (strlinenum, 10, ":%d", linenum); + VG_(strncat) (file, strlinenum, + FLEN - VG_(strlen)(file) - 1); + } + + if (hasfn || hasfile) + VG_(emit)( "%sin frame #%d, created by %s (%s)%s\n", + xpre, + ai->Addr.Stack.frameNo, + hasfn ? fn : "???", + hasfile ? file : "???", + xpost ); +#undef FLEN + } break; case Addr_Block: { diff --git a/include/pub_tool_addrinfo.h b/include/pub_tool_addrinfo.h index 342465a6a..bcfe2fd26 100644 --- a/include/pub_tool_addrinfo.h +++ b/include/pub_tool_addrinfo.h @@ -85,9 +85,15 @@ struct _AddrInfo { // As-yet unclassified. struct { } Undescribed; - // On a stack. + // On a stack. tid indicates which thread's stack? + // IP is the address of an instruction of the function where the + // stack address was. 0 if not found. + // frameNo is the frame nr of the call where the stack address was. + // -1 if not found. struct { - ThreadId tid; // Which thread's stack? + ThreadId tid; + Addr IP; + Int frameNo; } Stack; // This covers heap blocks (normal and from mempools), user-defined diff --git a/memcheck/tests/badfree.stderr.exp b/memcheck/tests/badfree.stderr.exp index a3ea7a413..b518703e3 100644 --- a/memcheck/tests/badfree.stderr.exp +++ b/memcheck/tests/badfree.stderr.exp @@ -7,4 +7,5 @@ Invalid free() / delete / delete[] / realloc() at 0x........: free (vg_replace_malloc.c:...) by 0x........: main (badfree.c:15) Address 0x........ is on thread 1's stack + in frame #1, created by main (badfree.c:7) diff --git a/memcheck/tests/badfree3.stderr.exp b/memcheck/tests/badfree3.stderr.exp index f276c3578..2e1a4bfde 100644 --- a/memcheck/tests/badfree3.stderr.exp +++ b/memcheck/tests/badfree3.stderr.exp @@ -7,4 +7,5 @@ Invalid free() / delete / delete[] / realloc() at 0x........: free (coregrind/vg_replace_malloc.c:...) by 0x........: main (memcheck/tests/badfree.c:15) Address 0x........ is on thread 1's stack + in frame #1, created by main (badfree.c:7) diff --git a/memcheck/tests/linux/rfcomm.stderr.exp b/memcheck/tests/linux/rfcomm.stderr.exp index 4df935b01..293ae2ba6 100644 --- a/memcheck/tests/linux/rfcomm.stderr.exp +++ b/memcheck/tests/linux/rfcomm.stderr.exp @@ -2,6 +2,7 @@ Syscall param socketcall.bind(my_addr.sa_family) points to uninitialised byte(s) ... by 0x........: main (rfcomm.c:40) Address 0x........ is on thread 1's stack + in frame #1, created by main (rfcomm.c:25) Uninitialised value was created by a stack allocation at 0x........: main (rfcomm.c:25) @@ -9,6 +10,7 @@ Syscall param socketcall.bind(my_addr.rc_bdaddr) points to uninitialised byte(s) ... by 0x........: main (rfcomm.c:44) Address 0x........ is on thread 1's stack + in frame #1, created by main (rfcomm.c:25) Uninitialised value was created by a stack allocation at 0x........: main (rfcomm.c:25) @@ -16,6 +18,7 @@ Syscall param socketcall.bind(my_addr.rc_channel) points to uninitialised byte(s ... by 0x........: main (rfcomm.c:48) Address 0x........ is on thread 1's stack + in frame #1, created by main (rfcomm.c:25) Uninitialised value was created by a stack allocation at 0x........: main (rfcomm.c:25) diff --git a/memcheck/tests/sendmsg.stderr.exp b/memcheck/tests/sendmsg.stderr.exp index 38e20c5dc..3a6d15699 100644 --- a/memcheck/tests/sendmsg.stderr.exp +++ b/memcheck/tests/sendmsg.stderr.exp @@ -2,5 +2,6 @@ Syscall param sendmsg(msg) points to uninitialised byte(s) at 0x........: sendmsg (in /...libc...) by 0x........: main (sendmsg.c:45) Address 0x........ is on thread 1's stack + in frame #1, created by main (sendmsg.c:12) sendmsg: 6 diff --git a/memcheck/tests/x86-linux/scalar.stderr.exp b/memcheck/tests/x86-linux/scalar.stderr.exp index 2114db99b..9ed5406a9 100644 --- a/memcheck/tests/x86-linux/scalar.stderr.exp +++ b/memcheck/tests/x86-linux/scalar.stderr.exp @@ -891,6 +891,7 @@ Syscall param old_select(args) points to uninitialised byte(s) ... by 0x........: main (scalar.c:394) Address 0x........ is on thread 1's stack + in frame #1, created by main (scalar.c:28) Syscall param old_select(readfds) points to unaddressable byte(s) ... @@ -984,6 +985,7 @@ Syscall param old_mmap(args) points to uninitialised byte(s) ... by 0x........: main (scalar.c:429) Address 0x........ is on thread 1's stack + in frame #1, created by main (scalar.c:28) ----------------------------------------------------- 91: __NR_munmap 2s 0m @@ -2385,11 +2387,13 @@ Syscall param sigaltstack(ss) points to unaddressable byte(s) ... by 0x........: main (scalar.c:834) Address 0x........ is on thread 1's stack + in frame #1, created by main (scalar.c:28) Syscall param sigaltstack(oss) points to unaddressable byte(s) ... by 0x........: main (scalar.c:834) Address 0x........ is on thread 1's stack + in frame #1, created by main (scalar.c:28) ----------------------------------------------------- 187: __NR_sendfile 4s 1m diff --git a/memcheck/tests/xml1.stderr.exp b/memcheck/tests/xml1.stderr.exp index b6cb890b2..3eba80599 100644 --- a/memcheck/tests/xml1.stderr.exp +++ b/memcheck/tests/xml1.stderr.exp @@ -334,6 +334,7 @@ Address 0x........ is on thread 1's stack + in frame #1, created by frame3 (xml1.c:7)