Author: sewardj
Date: 2008-01-10 17:54:50 +0000 (Thu, 10 Jan 2008)
New Revision: 7337

Log:
Push data-symbol awareness through to the debuginfo query machinery in
debuginfo.c, and connect Memcheck's describe-an-address device to it.
This makes Memcheck able to issue errors like this

 Uninitialised byte(s) found during client check request
    at 0x4005FE: croak (dsyms2.c:23)
    by 0x40066D: main (dsyms2.c:49)
  Address 0x601043 is 7 bytes inside global var "global_i2"

Not terribly useful, but it's a start.

Modified:
   branches/DATASYMS/coregrind/m_debuginfo/debuginfo.c
   branches/DATASYMS/coregrind/m_debuginfo/priv_storage.h
   branches/DATASYMS/coregrind/m_debuginfo/storage.c
   branches/DATASYMS/coregrind/m_redir.c
   branches/DATASYMS/exp-drd/drd_error.c
   branches/DATASYMS/include/pub_tool_debuginfo.h
   branches/DATASYMS/memcheck/mc_main.c


Modified: branches/DATASYMS/coregrind/m_debuginfo/debuginfo.c
===================================================================
--- branches/DATASYMS/coregrind/m_debuginfo/debuginfo.c 2008-01-10 14:31:54 UTC 
(rev 7336)
+++ branches/DATASYMS/coregrind/m_debuginfo/debuginfo.c 2008-01-10 17:54:50 UTC 
(rev 7337)
@@ -680,22 +680,42 @@
 
 /* Search all symtabs that we know about to locate ptr.  If found, set
    *pdi to the relevant DebugInfo, and *symno to the symtab entry
-   *number within that.  If not found, *psi is set to NULL. */
+   *number within that.  If not found, *psi is set to NULL.
+   If findText==True,  only text symbols are searched for.
+   If findText==False, only data symbols are searched for.
+*/
 static void search_all_symtabs ( Addr ptr, /*OUT*/DebugInfo** pdi,
                                            /*OUT*/Int* symno,
-                                 Bool match_anywhere_in_fun )
+                                 Bool match_anywhere_in_sym,
+                                 Bool findText )
 {
    Int        sno;
    DebugInfo* di;
+   Bool       inRange;
+
    for (di = debugInfo_list; di != NULL; di = di->next) {
-      if (di->text_avma <= ptr 
-          && ptr < di->text_avma + di->text_size) {
-         sno = ML_(search_one_symtab) ( di, ptr, match_anywhere_in_fun );
-         if (sno == -1) goto not_found;
-         *symno = sno;
-         *pdi = di;
-         return;
+
+      if (findText) {
+         inRange = di->text_size > 0
+                   && di->text_avma <= ptr 
+                   && ptr < di->text_avma + di->text_size;
+      } else {
+         inRange = di->data_size > 0
+                   && di->data_avma <= ptr 
+                   && ptr < di->data_avma + di->data_size + di->bss_size;
       }
+
+      /* Note this short-circuit check relies on the assumption that
+         .bss is mapped immediately after .data. */
+      if (!inRange) continue;
+
+      sno = ML_(search_one_symtab) ( 
+               di, ptr, match_anywhere_in_sym, findText );
+      if (sno == -1) goto not_found;
+      *symno = sno;
+      *pdi = di;
+      return;
+
    }
   not_found:
    *pdi = NULL;
@@ -729,16 +749,19 @@
    plausible symbol name.  Returns False if no idea; otherwise True.
    Caller supplies buf and nbuf.  If demangle is False, don't do
    demangling, regardless of VG_(clo_demangle) -- probably because the
-   call has come from VG_(get_fnname_nodemangle)(). */
+   call has come from VG_(get_fnname_nodemangle)().  findText
+   indicates whether we're looking for a text symbol or a data symbol
+   -- caller must choose one kind or the other. */
 static
-Bool get_fnname ( Bool demangle, Addr a, Char* buf, Int nbuf,
-                  Bool match_anywhere_in_fun, Bool show_offset)
+Bool get_sym_name ( Bool demangle, Addr a, Char* buf, Int nbuf,
+                    Bool match_anywhere_in_sym, Bool show_offset,
+                    Bool findText, /*OUT*/OffT* offsetP )
 {
    DebugInfo* di;
    Int        sno;
    Int        offset;
 
-   search_all_symtabs ( a, &di, &sno, match_anywhere_in_fun );
+   search_all_symtabs ( a, &di, &sno, match_anywhere_in_sym, findText );
    if (di == NULL) 
       return False;
    if (demangle) {
@@ -749,6 +772,8 @@
    }
 
    offset = a - di->symtab[sno].addr;
+   if (offsetP) *offsetP = (OffT)offset;
+
    if (show_offset && offset != 0) {
       Char     buf2[12];
       Char*    symend = buf + VG_(strlen)(buf);
@@ -777,7 +802,9 @@
    DebugInfo* si;
    Int        sno;
    search_all_symtabs ( guest_code_addr, 
-                        &si, &sno, True/*match_anywhere_in_fun*/ );
+                        &si, &sno,
+                        True/*match_anywhere_in_fun*/,
+                        True/*consider text symbols only*/ );
    if (si == NULL) 
       return 0;
    else
@@ -788,18 +815,22 @@
    match anywhere in function, but don't show offsets. */
 Bool VG_(get_fnname) ( Addr a, Char* buf, Int nbuf )
 {
-   return get_fnname ( /*demangle*/True, a, buf, nbuf,
-                       /*match_anywhere_in_fun*/True, 
-                       /*show offset?*/False );
+   return get_sym_name ( /*demangle*/True, a, buf, nbuf,
+                         /*match_anywhere_in_fun*/True, 
+                         /*show offset?*/False,
+                         /*text syms only*/True,
+                         /*offsetP*/NULL );
 }
 
 /* This is available to tools... always demangle C++ names,
    match anywhere in function, and show offset if nonzero. */
 Bool VG_(get_fnname_w_offset) ( Addr a, Char* buf, Int nbuf )
 {
-   return get_fnname ( /*demangle*/True, a, buf, nbuf,
-                       /*match_anywhere_in_fun*/True, 
-                       /*show offset?*/True );
+   return get_sym_name ( /*demangle*/True, a, buf, nbuf,
+                         /*match_anywhere_in_fun*/True, 
+                         /*show offset?*/True,
+                         /*text syms only*/True,
+                         /*offsetP*/NULL );
 }
 
 /* This is available to tools... always demangle C++ names,
@@ -807,18 +838,22 @@
    and don't show offsets. */
 Bool VG_(get_fnname_if_entry) ( Addr a, Char* buf, Int nbuf )
 {
-   return get_fnname ( /*demangle*/True, a, buf, nbuf,
-                       /*match_anywhere_in_fun*/False, 
-                       /*show offset?*/False );
+   return get_sym_name ( /*demangle*/True, a, buf, nbuf,
+                         /*match_anywhere_in_fun*/False, 
+                         /*show offset?*/False,
+                         /*text syms only*/True,
+                         /*offsetP*/NULL );
 }
 
 /* This is only available to core... don't demangle C++ names,
    match anywhere in function, and don't show offsets. */
 Bool VG_(get_fnname_nodemangle) ( Addr a, Char* buf, Int nbuf )
 {
-   return get_fnname ( /*demangle*/False, a, buf, nbuf,
-                       /*match_anywhere_in_fun*/True, 
-                       /*show offset?*/False );
+   return get_sym_name ( /*demangle*/False, a, buf, nbuf,
+                         /*match_anywhere_in_fun*/True, 
+                         /*show offset?*/False,
+                         /*text syms only*/True,
+                         /*offsetP*/NULL );
 }
 
 /* This is only available to core... don't demangle C++ names, but do
@@ -830,9 +865,11 @@
    Char tmpbuf[N_TMPBUF];
    Bool ok;
    vg_assert(nbuf > 0);
-   ok = get_fnname ( /*demangle*/False, a, tmpbuf, N_TMPBUF,
-                     /*match_anywhere_in_fun*/True, 
-                     /*show offset?*/False );
+   ok = get_sym_name ( /*demangle*/False, a, tmpbuf, N_TMPBUF,
+                       /*match_anywhere_in_fun*/True, 
+                       /*show offset?*/False,
+                       /*text syms only*/True,
+                       /*offsetP*/NULL );
    tmpbuf[N_TMPBUF-1] = 0; /* paranoia */
    if (!ok) 
       return False;
@@ -845,6 +882,28 @@
 #  undef N_TMPBUF
 }
 
+/* Looks up 'a' in the collection of data symbols, and if found puts
+   its name (or as much as will fit) into dname[0 .. n_dname-1]
+   including zero terminator.  Also the 'a's offset from the symbol
+   start is put into *offset. */
+Bool VG_(get_dataname_and_offset)( Addr a,
+                                   /*OUT*/Char* dname, Int n_dname,
+                                   /*OUT*/OffT* offset )
+{
+   Bool ok;
+   vg_assert(n_dname > 1);
+   ok = get_sym_name ( /*demangle*/False, a, dname, n_dname,
+                       /*match_anywhere_in_sym*/True, 
+                       /*show offset?*/False,
+                       /*data syms only please*/False,
+                       offset );
+   if (!ok)
+      return False;
+   dname[n_dname-1] = 0;
+   return True;
+}
+
+
 /* Map a code address to the name of a shared object file or the
    executable.  Returns False if no idea; otherwise True.  Doesn't
    require debug info.  Caller supplies buf and nbuf. */
@@ -1537,13 +1596,15 @@
                                /*OUT*/Addr*   addr,
                                /*OUT*/Addr*   tocptr,
                                /*OUT*/UInt*   size,
-                               /*OUT*/HChar** name )
+                               /*OUT*/HChar** name,
+                               /*OUT*/Bool*   isText )
 {
    vg_assert(idx >= 0 && idx < si->symtab_used);
    if (addr)   *addr   = si->symtab[idx].addr;
    if (tocptr) *tocptr = si->symtab[idx].tocptr;
    if (size)   *size   = si->symtab[idx].size;
    if (name)   *name   = (HChar*)si->symtab[idx].name;
+   if (isText) *isText = si->symtab[idx].isText;
 }
 
 

Modified: branches/DATASYMS/coregrind/m_debuginfo/priv_storage.h
===================================================================
--- branches/DATASYMS/coregrind/m_debuginfo/priv_storage.h      2008-01-10 
14:31:54 UTC (rev 7336)
+++ branches/DATASYMS/coregrind/m_debuginfo/priv_storage.h      2008-01-10 
17:54:50 UTC (rev 7337)
@@ -359,7 +359,8 @@
 /* Find a symbol-table index containing the specified pointer, or -1
    if not found.  Binary search.  */
 extern Int ML_(search_one_symtab) ( struct _DebugInfo* di, Addr ptr,
-                                    Bool match_anywhere_in_fun );
+                                    Bool match_anywhere_in_sym,
+                                    Bool findText );
 
 /* Find a location-table index containing the specified pointer, or -1
    if not found.  Binary search.  */

Modified: branches/DATASYMS/coregrind/m_debuginfo/storage.c
===================================================================
--- branches/DATASYMS/coregrind/m_debuginfo/storage.c   2008-01-10 14:31:54 UTC 
(rev 7336)
+++ branches/DATASYMS/coregrind/m_debuginfo/storage.c   2008-01-10 17:54:50 UTC 
(rev 7337)
@@ -915,10 +915,11 @@
    if not found.  Binary search.  */
 
 Int ML_(search_one_symtab) ( struct _DebugInfo* di, Addr ptr,
-                             Bool match_anywhere_in_fun )
+                             Bool match_anywhere_in_sym,
+                             Bool findText )
 {
    Addr a_mid_lo, a_mid_hi;
-   Int  mid, size, 
+   Word mid, size, 
         lo = 0, 
         hi = di->symtab_used-1;
    while (True) {
@@ -926,7 +927,7 @@
       if (lo > hi) return -1; /* not found */
       mid      = (lo + hi) / 2;
       a_mid_lo = di->symtab[mid].addr;
-      size = ( match_anywhere_in_fun
+      size = ( match_anywhere_in_sym
              ? di->symtab[mid].size
              : 1);
       a_mid_hi = ((Addr)di->symtab[mid].addr) + size - 1;
@@ -934,7 +935,11 @@
       if (ptr < a_mid_lo) { hi = mid-1; continue; } 
       if (ptr > a_mid_hi) { lo = mid+1; continue; }
       vg_assert(ptr >= a_mid_lo && ptr <= a_mid_hi);
-      return mid;
+      /* Found a symbol with the correct address range.  But is it
+         of the right kind (text vs data) ? */
+      if (  findText   &&   di->symtab[mid].isText  ) return mid;
+      if ( (!findText) && (!di->symtab[mid].isText) ) return mid;
+      return -1;
    }
 }
 
@@ -945,7 +950,7 @@
 Int ML_(search_one_loctab) ( struct _DebugInfo* di, Addr ptr )
 {
    Addr a_mid_lo, a_mid_hi;
-   Int  mid, 
+   Word mid, 
         lo = 0, 
         hi = di->loctab_used-1;
    while (True) {

Modified: branches/DATASYMS/coregrind/m_redir.c
===================================================================
--- branches/DATASYMS/coregrind/m_redir.c       2008-01-10 14:31:54 UTC (rev 
7336)
+++ branches/DATASYMS/coregrind/m_redir.c       2008-01-10 17:54:50 UTC (rev 
7337)
@@ -327,6 +327,7 @@
    HChar        demangled_sopatt[N_DEMANGLED];
    HChar        demangled_fnpatt[N_DEMANGLED];
    Bool         check_ppcTOCs = False;
+   Bool         isText;
    const UChar* newsi_soname;
 
 #  if defined(VG_PLAT_USES_PPCTOC)
@@ -349,9 +350,12 @@
    nsyms = VG_(seginfo_syms_howmany)( newsi );
    for (i = 0; i < nsyms; i++) {
       VG_(seginfo_syms_getidx)( newsi, i, &sym_addr, &sym_toc, 
-                                          NULL, &sym_name );
+                                          NULL, &sym_name, &isText );
       ok = VG_(maybe_Z_demangle)( sym_name, demangled_sopatt, N_DEMANGLED,
                                   demangled_fnpatt, N_DEMANGLED, &isWrap );
+      /* ignore data symbols */
+      if (!isText)
+         continue;
       if (!ok) {
          /* It's not a full-scale redirect, but perhaps it is a load-notify
             fn?  Let the load-notify department see it. */
@@ -384,9 +388,11 @@
    if (check_ppcTOCs) {
       for (i = 0; i < nsyms; i++) {
          VG_(seginfo_syms_getidx)( newsi, i, &sym_addr, &sym_toc, 
-                                             NULL, &sym_name );
-         ok = VG_(maybe_Z_demangle)( sym_name, demangled_sopatt, N_DEMANGLED,
-                                     demangled_fnpatt, N_DEMANGLED, &isWrap );
+                                             NULL, &sym_name, &isText );
+         ok = isText
+              && VG_(maybe_Z_demangle)( 
+                    sym_name, demangled_sopatt, N_DEMANGLED,
+                    demangled_fnpatt, N_DEMANGLED, &isWrap );
          if (!ok)
             /* not a redirect.  Ignore. */
             continue;
@@ -480,7 +486,7 @@
      )
 {
    Spec*  sp;
-   Bool   anyMark;
+   Bool   anyMark, isText;
    Active act;
    Int    nsyms, i;
    Addr   sym_addr;
@@ -505,8 +511,13 @@
       of trashing the caches less. */
    nsyms = VG_(seginfo_syms_howmany)( di );
    for (i = 0; i < nsyms; i++) {
-      VG_(seginfo_syms_getidx)( di, i, &sym_addr, NULL, NULL, &sym_name );
+      VG_(seginfo_syms_getidx)( di, i,
+                                &sym_addr, NULL, NULL, &sym_name, &isText );
 
+      /* ignore data symbols */
+      if (!isText)
+         continue;
+
       /* On AIX, we cannot redirect calls to a so-called glink
          function for reasons which are not obvious - something to do
          with saving r2 across the call.  Not a problem, as we don't

Modified: branches/DATASYMS/exp-drd/drd_error.c
===================================================================
--- branches/DATASYMS/exp-drd/drd_error.c       2008-01-10 14:31:54 UTC (rev 
7336)
+++ branches/DATASYMS/exp-drd/drd_error.c       2008-01-10 17:54:50 UTC (rev 
7337)
@@ -103,9 +103,10 @@
          HChar* name;
          Char filename[256];
          Int linenum;
+         Bool isText;
 
-         VG_(seginfo_syms_getidx)(sg, i, &addr, &tocptr, &size, &name);
-         if (addr <= a && a < addr + size)
+         VG_(seginfo_syms_getidx)(sg, i, &addr, &tocptr, &size, &name, 
&isText);
+         if (isText && addr <= a && a < addr + size)
          {
             ai->size     = size;
             ai->rwoffset = a - addr;

Modified: branches/DATASYMS/include/pub_tool_debuginfo.h
===================================================================
--- branches/DATASYMS/include/pub_tool_debuginfo.h      2008-01-10 14:31:54 UTC 
(rev 7336)
+++ branches/DATASYMS/include/pub_tool_debuginfo.h      2008-01-10 17:54:50 UTC 
(rev 7337)
@@ -74,6 +74,14 @@
    entry points within it. */
 extern Bool VG_(get_fnname_if_entry) ( Addr a, Char* fnname, Int n_fnname );
 
+/* Looks up 'a' in the collection of data symbols, and if found puts
+   its name (or as much as will fit) into dname[0 .. n_dname-1]
+   including zero terminator.  Also the 'a's offset from the symbol
+   start is put into *offset. */
+extern Bool VG_(get_dataname_and_offset)( Addr a,
+                                          /*OUT*/Char* dname, Int n_dname,
+                                          /*OUT*/OffT* offset );
+
 /* Succeeds if the address is within a shared object or the main executable.
    It doesn't matter if debug info is present or not. */
 extern Bool VG_(get_objname)  ( Addr a, Char* objname,  Int n_objname );
@@ -87,7 +95,6 @@
 */
 extern Char* VG_(describe_IP)(Addr eip, Char* buf, Int n_buf);
 
-
 /*====================================================================*/
 /*=== Obtaining segment information                                ===*/
 /*====================================================================*/
@@ -121,8 +128,8 @@
                                         /*OUT*/Addr*   addr,
                                         /*OUT*/Addr*   tocptr,
                                         /*OUT*/UInt*   size,
-                                        /*OUT*/HChar** name );
-
+                                        /*OUT*/HChar** name,
+                                        /*OUT*/Bool*   isText );
 typedef
    enum {
       Vg_SectUnknown,

Modified: branches/DATASYMS/memcheck/mc_main.c
===================================================================
--- branches/DATASYMS/memcheck/mc_main.c        2008-01-10 14:31:54 UTC (rev 
7336)
+++ branches/DATASYMS/memcheck/mc_main.c        2008-01-10 17:54:50 UTC (rev 
7337)
@@ -44,6 +44,7 @@
 #include "pub_tool_tooliface.h"
 #include "pub_tool_threadstate.h"
 #include "pub_tool_oset.h"
+#include "pub_tool_debuginfo.h"     // VG_(get_dataname_and_offset)
 
 #include "mc_include.h"
 #include "memcheck.h"   /* for client requests */
@@ -2629,6 +2630,7 @@
       Addr_Unknown,       // classification yielded nothing useful
       Addr_Stack,          
       Addr_Block,
+      Addr_GlobalData
    }
    AddrTag;
 
@@ -2657,6 +2659,13 @@
          ExeContext* lastchange;
       } Block;
 
+      // In a global .data symbol.  This holds the first 63 chars of
+      // the variable's (zero terminated), plus an offset.
+      struct {
+         Char name[64];
+         OffT offset;
+      } GlobalData;
+
       // Classification yielded nothing useful.
       struct { } Unknown;
 
@@ -2833,6 +2842,17 @@
          break;
       }
 
+      case Addr_GlobalData:
+         VG_(message)(Vg_UserMsg, 
+                      "%sAddress 0x%llx is %llu bytes "
+                        "inside global var \"%t\"%s", 
+                      xpre, 
+                      (ULong)a, 
+                      (ULong)ai->Addr.GlobalData.offset,
+                      ai->Addr.GlobalData.name, 
+                      xpost);
+         break;
+
       default:
          VG_(tool_panic)("mc_pp_AddrInfo");
    }
@@ -3330,9 +3350,9 @@
    tl_assert(Addr_Undescribed == ai->tag);
 
    /* Perhaps it's a user-def'd block? */
-   if (client_perm_maybe_describe( a, ai ))
+   if (client_perm_maybe_describe( a, ai )) {
       return;
-
+   }
    /* Perhaps it's on a thread's stack? */
    VG_(thread_stack_reset_iter)();
    while ( VG_(thread_stack_next)(&tid, &stack_min, &stack_max) ) {
@@ -3369,6 +3389,17 @@
          return;
       }
    }
+   /* Perhaps it's in global data? */
+   VG_(memset)( &ai->Addr.GlobalData.name, 0, 
sizeof(ai->Addr.GlobalData.name));
+   if (VG_(get_dataname_and_offset)(
+          a, &ai->Addr.GlobalData.name[0],
+             sizeof(ai->Addr.GlobalData.name)-1,
+             &ai->Addr.GlobalData.offset )) {
+      ai->tag = Addr_GlobalData;
+      tl_assert( ai->Addr.GlobalData.name
+                    [ sizeof(ai->Addr.GlobalData.name)-1 ] == 0);
+      return;
+   }
    /* Clueless ... */
    ai->tag = Addr_Unknown;
    return;


-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace
_______________________________________________
Valgrind-developers mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/valgrind-developers

Reply via email to