Improve address description for address in the stack.

--read-var-info=yes is very memory and cpu intensive.
This patch ensures that even witout --read-var-info=yes that
the frame where the address point is reported in the address
description.



git-svn-id: svn://svn.valgrind.org/valgrind/trunk@13991
This commit is contained in:
Philippe Waroquiers 2014-05-22 23:48:24 +00:00
parent 104fc12674
commit 9b67d18f11
9 changed files with 98 additions and 9 deletions

4
NEWS
View File

@ -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 <address>'

View File

@ -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: {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -334,6 +334,7 @@
</frame>
</stack>
<auxwhat>Address 0x........ is on thread 1's stack</auxwhat>
<auxwhat>in frame #1, created by frame3 (xml1.c:7)</auxwhat>
</error>
<error>