]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Improve address description for address in the stack.
authorPhilippe Waroquiers <philippe.waroquiers@skynet.be>
Thu, 22 May 2014 23:48:24 +0000 (23:48 +0000)
committerPhilippe Waroquiers <philippe.waroquiers@skynet.be>
Thu, 22 May 2014 23:48:24 +0000 (23:48 +0000)
--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

NEWS
coregrind/m_addrinfo.c
include/pub_tool_addrinfo.h
memcheck/tests/badfree.stderr.exp
memcheck/tests/badfree3.stderr.exp
memcheck/tests/linux/rfcomm.stderr.exp
memcheck/tests/sendmsg.stderr.exp
memcheck/tests/x86-linux/scalar.stderr.exp
memcheck/tests/xml1.stderr.exp

diff --git a/NEWS b/NEWS
index 0f78103c1f052da5bfa64efc9aab7a84197ada2c..d94c4bd10d75eb365b2cd2c314a591c003a5c607 100644 (file)
--- 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 <address>'
index bcf691370b9510f38b02070069b43aa233667ae3..63393318257276f01a02a662cd80bb76ec931dc3 100644 (file)
 #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: {
index 342465a6a2c54e7a29d0e6abafe6cd64b15f5659..bcfe2fd263967282aead34384a51e8fe14bb92cc 100644 (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
index a3ea7a413eaaff9c8faa3e1695cfef85f486b270..b518703e34bc3e47e83d30f53983d31d1d47a391 100644 (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)
 
index f276c3578a0dff05ed4d56cb489f42e7d4c800d2..2e1a4bfdefdc7a70f724bf53bf17973be1bd5cd9 100644 (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)
 
index 4df935b015b86b31def01a128ae56065d66fdf8c..293ae2ba6ef2284fc896712f30f761df743d0e07 100644 (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)
 
index 38e20c5dc8d164df43e01359ee50a52bfd20aa18..3a6d15699f7dc5f805352cd605ccbabc47553b6c 100644 (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
index 2114db99b86d2409c87f3c02f60abb0c063a48b5..9ed5406a927038784fbd2b30608b98d0d063bbfc 100644 (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
index b6cb890b26ad0b33fbd06fab4c5c21e317c87c16..3eba805995989e4031d2eddf11319bd98a753a92 100644 (file)
     </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>