|
[Valgrind-developers] valgrind: r7403 - in branches/DATASYMS:
coregrind/m_debuginfo include memcheck
From: <sv...@va...> - 2008-02-12 20:18:11
|
Author: sewardj
Date: 2008-02-12 20:18:11 +0000 (Tue, 12 Feb 2008)
New Revision: 7403
Log:
Format descriptions of data addresses in a better way.
Modified:
branches/DATASYMS/coregrind/m_debuginfo/debuginfo.c
branches/DATASYMS/coregrind/m_debuginfo/priv_tytypes.h
branches/DATASYMS/coregrind/m_debuginfo/readdwarf3.c
branches/DATASYMS/coregrind/m_debuginfo/tytypes.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-02-12 13:54:28 UTC (rev 7402)
+++ branches/DATASYMS/coregrind/m_debuginfo/debuginfo.c 2008-02-12 20:18:11 UTC (rev 7403)
@@ -999,13 +999,169 @@
}
}
+
+/* Format the acquired information into dname1[0 .. n_dname-1] and
+ dname2[0 .. n_dname-1] in an understandable way. Not so easy.
+ If frameNo is -1, this is assumed to be a global variable; else
+ a local variable. */
+static void format_message ( /*OUT*/Char* dname1,
+ /*OUT*/Char* dname2,
+ Int n_dname,
+ Addr data_addr,
+ DiVariable* var,
+ OffT var_offset,
+ OffT residual_offset,
+ XArray* /*UChar*/ described,
+ Int frameNo,
+ ThreadId tid )
+{
+ Bool have_descr, have_srcloc;
+ UChar* vo_plural = var_offset == 1 ? "" : "s";
+ UChar* ro_plural = residual_offset == 1 ? "" : "s";
+
+ vg_assert(frameNo >= -1);
+ vg_assert(dname1 && dname2 && n_dname > 1);
+ vg_assert(described);
+ vg_assert(var && var->name);
+ have_descr = VG_(sizeXA)(described) > 0
+ && *(UChar*)VG_(indexXA)(described,0) != '\0';
+ have_srcloc = var->fileName && var->lineNo > 0;
+
+ dname1[0] = dname2[0] = '\0';
+
+ /* ------ local cases ------ */
+
+ if ( frameNo >= 0 && (!have_srcloc) && (!have_descr) ) {
+ /* no srcloc, no description:
+ Address 0x7fefff6cf is 543 bytes inside local var "a",
+ in frame #1 of thread 1
+ */
+ VG_(snprintf)(
+ dname1, n_dname,
+ "Address 0x%lx is %lu byte%s inside local var \"%s\",",
+ data_addr, var_offset, vo_plural, var->name );
+ VG_(snprintf)(
+ dname2, n_dname,
+ "in frame #%d of thread %d", frameNo, (Int)tid);
+ }
+ else
+ if ( frameNo >= 0 && have_srcloc && (!have_descr) ) {
+ /* no description:
+ Address 0x7fefff6cf is 543 bytes inside local var "a"
+ declared at dsyms7.c:17, in frame #1 of thread 1
+ */
+ VG_(snprintf)(
+ dname1, n_dname,
+ "Address 0x%lx is %lu byte%s inside local var \"%s\"",
+ data_addr, var_offset, vo_plural, var->name );
+ VG_(snprintf)(
+ dname2, n_dname,
+ "declared at %s:%d, in frame #%d of thread %d",
+ var->fileName, var->lineNo, frameNo, (Int)tid);
+ }
+ else
+ if ( frameNo >= 0 && (!have_srcloc) && have_descr ) {
+ /* no srcloc:
+ Address 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2
+ in frame #1 of thread 1
+ */
+ VG_(snprintf)(
+ dname1, n_dname,
+ "Address 0x%lx is %lu byte%s inside %s%s",
+ data_addr, residual_offset, ro_plural, var->name,
+ VG_(indexXA)(described,0) );
+ VG_(snprintf)(
+ dname2, n_dname,
+ "in frame #%d of thread %d", frameNo, (Int)tid);
+ }
+ else
+ if ( frameNo >= 0 && have_srcloc && have_descr ) {
+ /* Address 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2,
+ declared at dsyms7.c:17, in frame #1 of thread 1 */
+ VG_(snprintf)(
+ dname1, n_dname,
+ "Address 0x%lx is %lu byte%s inside %s%s,",
+ data_addr, residual_offset, ro_plural, var->name,
+ VG_(indexXA)(described,0) );
+ VG_(snprintf)(
+ dname2, n_dname,
+ "declared at %s:%d, in frame #%d of thread %d",
+ var->fileName, var->lineNo, frameNo, (Int)tid);
+ }
+ else
+ /* ------ global cases ------ */
+ if ( frameNo >= -1 && (!have_srcloc) && (!have_descr) ) {
+ /* no srcloc, no description:
+ Address 0x7fefff6cf is 543 bytes inside global var "a"
+ */
+ VG_(snprintf)(
+ dname1, n_dname,
+ "Address 0x%lx is %lu byte%s inside global var \"%s\"",
+ data_addr, var_offset, vo_plural, var->name );
+ }
+ else
+ if ( frameNo >= -1 && have_srcloc && (!have_descr) ) {
+ /* no description:
+ Address 0x7fefff6cf is 543 bytes inside global var "a"
+ declared at dsyms7.c:17
+ */
+ VG_(snprintf)(
+ dname1, n_dname,
+ "Address 0x%lx is %lu byte%s inside global var \"%s\"",
+ data_addr, var_offset, vo_plural, var->name );
+ VG_(snprintf)(
+ dname2, n_dname,
+ "declared at %s:%d",
+ var->fileName, var->lineNo);
+ }
+ else
+ if ( frameNo >= -1 && (!have_srcloc) && have_descr ) {
+ /* no srcloc:
+ Address 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2,
+ a global variable
+ */
+ VG_(snprintf)(
+ dname1, n_dname,
+ "Address 0x%lx is %lu byte%s inside %s%s,",
+ data_addr, residual_offset, ro_plural, var->name,
+ VG_(indexXA)(described,0) );
+ VG_(snprintf)(
+ dname2, n_dname,
+ "a global variable");
+ }
+ else
+ if ( frameNo >= -1 && have_srcloc && have_descr ) {
+ /* Address 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2,
+ a global variable declared at dsyms7.c:17 */
+ VG_(snprintf)(
+ dname1, n_dname,
+ "Address 0x%lx is %lu byte%s inside %s%s,",
+ data_addr, residual_offset, ro_plural, var->name,
+ VG_(indexXA)(described,0) );
+ VG_(snprintf)(
+ dname2, n_dname,
+ "a global variable declared at %s:%d",
+ var->fileName, var->lineNo);
+ }
+ else
+ vg_assert(0);
+
+ dname1[n_dname-1] = dname2[n_dname-1] = 0;
+}
+
+
/* Determine if data_addr is a local variable in the frame
characterised by (ip,sp,fp), and if so write its description into
- dname[0..n_dname-1], and return True. If not, return False. */
+ dname{1,2}[0..n_dname-1], and return True. If not, return
+ False. */
static
-Bool consider_vars_in_frame ( /*OUT*/Char* dname, Int n_dname,
+Bool consider_vars_in_frame ( /*OUT*/Char* dname1,
+ /*OUT*/Char* dname2,
+ Int n_dname,
Addr data_addr,
- Addr ip, Addr sp, Addr fp )
+ Addr ip, Addr sp, Addr fp,
+ /* shown to user: */
+ ThreadId tid, Int frameNo )
{
Word i;
DebugInfo* di;
@@ -1091,14 +1247,13 @@
DiVariable* var = (DiVariable*)VG_(indexXA)( vars, j );
SizeT offset;
if (data_address_is_in_var( &offset, var, ®s, data_addr )) {
- XArray* xa = ML_(describe_type)( var->type, offset );
- VG_(snprintf)(
- dname, (SizeT)n_dname,
- "Address 0x%lx is %lu bytes inside local var "
- "\"%s\" (%s) declared at %s:%d",
- data_addr, offset, var->name, VG_(indexXA)(xa,0),
- var->fileName ? var->fileName : "(unknown)", var->lineNo );
- dname[n_dname-1] = 0;
+ OffT residual_offset = 0;
+ XArray* described = ML_(describe_type)( &residual_offset,
+ var->type, offset );
+ format_message( dname1, dname2, n_dname,
+ data_addr, var, offset, residual_offset,
+ described, frameNo, tid );
+ VG_(deleteXA)( described );
return True;
}
}
@@ -1110,10 +1265,12 @@
/* Try to form some description of data_addr by looking at the DWARF3
debug info we have. This considers all global variables, and all
frames in the stacks of all threads. Result (or as much as will
- fit) is put into into dname[0 .. n_dname-1] and is guaranteed to be
- zero terminated. */
-Bool VG_(get_data_description)( Addr data_addr,
- /*OUT*/Char* dname, Int n_dname )
+ fit) is put into into dname{1,2}[0 .. n_dname-1] and is guaranteed
+ to be zero terminated. */
+Bool VG_(get_data_description)( /*OUT*/Char* dname1,
+ /*OUT*/Char* dname2,
+ Int n_dname,
+ Addr data_addr )
{
# define N_FRAMES 8
Addr ips[N_FRAMES], sps[N_FRAMES], fps[N_FRAMES];
@@ -1126,7 +1283,7 @@
Word j;
vg_assert(n_dname > 1);
- dname[n_dname-1] = 0;
+ dname1[n_dname-1] = dname2[n_dname-1] = 0;
if (0) VG_(printf)("GDD: dataaddr %p\n", data_addr);
@@ -1189,11 +1346,14 @@
if (data_address_is_in_var( &offset, var,
NULL/* RegSummary* */,
data_addr )) {
- VG_(snprintf)(
- dname, (SizeT)n_dname,
- "Address 0x%lx is %lu bytes inside global var \"%s\"",
- data_addr, offset, var->name);
- dname[n_dname-1] = 0;
+ OffT residual_offset = 0;
+ XArray* described = ML_(describe_type)( &residual_offset,
+ var->type, offset );
+ format_message( dname1, dname2, n_dname,
+ data_addr, var, offset, residual_offset,
+ described, -1/*frameNo*/, tid );
+ VG_(deleteXA)( described );
+ dname1[n_dname-1] = dname2[n_dname-1] = 0;
return True;
}
}
@@ -1215,8 +1375,10 @@
break;
}
}
- if (!found)
+ if (!found) {
+ dname1[n_dname-1] = dname2[n_dname-1] = 0;
return False;
+ }
/* We conclude data_addr is in thread tid's stack. Unwind the
stack to get a bunch of (ip,sp,fp) triples describing the
@@ -1226,15 +1388,16 @@
sps, fps, 0/*first_ip_delta*/ );
vg_assert(n_frames >= 0 && n_frames <= N_FRAMES);
for (j = 0; j < n_frames; j++) {
- if (consider_vars_in_frame( dname, n_dname,
+ if (consider_vars_in_frame( dname1, dname2, n_dname,
data_addr,
- ips[j], sps[j], fps[j] )) {
- dname[n_dname-1] = 0;
+ ips[j], sps[j], fps[j], tid, j )) {
+ dname1[n_dname-1] = dname2[n_dname-1] = 0;
return True;
}
}
/* We didn't find anything useful. */
+ dname1[n_dname-1] = dname2[n_dname-1] = 0;
return False;
# undef N_FRAMES
}
Modified: branches/DATASYMS/coregrind/m_debuginfo/priv_tytypes.h
===================================================================
--- branches/DATASYMS/coregrind/m_debuginfo/priv_tytypes.h 2008-02-12 13:54:28 UTC (rev 7402)
+++ branches/DATASYMS/coregrind/m_debuginfo/priv_tytypes.h 2008-02-12 20:18:11 UTC (rev 7403)
@@ -151,8 +151,10 @@
/* FIXME: check all pointers before dereferencing */
SizeT ML_(sizeOfType)( Type* ty );
-/* Describe where in the type 'offset' falls. */
-XArray* /*UChar*/ ML_(describe_type)( Type* ty, OffT offset );
+/* Describe where in the type 'offset' falls. Caller must
+ deallocate the resulting XArray. */
+XArray* /*UChar*/ ML_(describe_type)( /*OUT*/OffT* residual_offset,
+ Type* ty, OffT offset );
#endif /* ndef __PRIV_TYTYPES_H */
Modified: branches/DATASYMS/coregrind/m_debuginfo/readdwarf3.c
===================================================================
--- branches/DATASYMS/coregrind/m_debuginfo/readdwarf3.c 2008-02-12 13:54:28 UTC (rev 7402)
+++ branches/DATASYMS/coregrind/m_debuginfo/readdwarf3.c 2008-02-12 20:18:11 UTC (rev 7403)
@@ -1350,7 +1350,19 @@
CUConst* cc, UWord debug_line_offset,
Bool td3 )
{
+ Bool is_dw64;
Cursor c;
+ Word i;
+ ULong unit_length;
+ UShort version;
+ ULong header_length;
+ UChar minimum_instruction_length;
+ UChar default_is_stmt;
+ Char line_base;
+ UChar line_range;
+ UChar opcode_base;
+ UChar* str;
+
vg_assert(parser && cc && cc->barf);
if ((!cc->debug_line_img)
|| cc->debug_line_sz <= debug_line_offset)
@@ -1360,20 +1372,20 @@
cc->debug_line_sz, debug_line_offset, cc->barf,
"Overrun whilst reading .debug_line section(1)" );
- Bool is_dw64;
- ULong unit_length = get_Initial_Length( &is_dw64, &c, "read_filename_table: invalid initial-length field" );
- UShort version = get_UShort( &c );
+ unit_length
+ = get_Initial_Length( &is_dw64, &c,
+ "read_filename_table: invalid initial-length field" );
+ version = get_UShort( &c );
if (version != 2)
cc->barf("read_filename_table: Only DWARF version 2 line info "
"is currently supported.");
- ULong header_length = (ULong)get_Dwarfish_UWord( &c, is_dw64 );
- UChar minimum_instruction_length = get_UChar( &c );
- UChar default_is_stmt = get_UChar( &c );
- Char line_base = (Char)get_UChar( &c );
- UChar line_range = get_UChar( &c );
- UChar opcode_base = get_UChar( &c );
+ header_length = (ULong)get_Dwarfish_UWord( &c, is_dw64 );
+ minimum_instruction_length = get_UChar( &c );
+ default_is_stmt = get_UChar( &c );
+ line_base = (Char)get_UChar( &c );
+ line_range = get_UChar( &c );
+ opcode_base = get_UChar( &c );
/* skip over "standard_opcode_lengths" */
- Word i;
for (i = 1; i < (Word)opcode_base; i++)
(void)get_UChar( &c );
@@ -1388,7 +1400,7 @@
vg_assert( VG_(sizeXA)( parser->filenameTable ) == 0 );
/* Add a dummy index-zero entry. DWARF3 numbers its files
from 1, for some reason. */
- UChar* str = ML_(dinfo_strdup)( "<unknown>" );;
+ str = ML_(dinfo_strdup)( "<unknown>" );;
VG_(addToXA)( parser->filenameTable, &str );
while (peek_UChar(&c) != 0) {
str = get_AsciiZ(&c);
Modified: branches/DATASYMS/coregrind/m_debuginfo/tytypes.c
===================================================================
--- branches/DATASYMS/coregrind/m_debuginfo/tytypes.c 2008-02-12 13:54:28 UTC (rev 7402)
+++ branches/DATASYMS/coregrind/m_debuginfo/tytypes.c 2008-02-12 20:18:11 UTC (rev 7403)
@@ -340,7 +340,10 @@
}
-XArray* /*UChar*/ ML_(describe_type)( Type* ty, OffT offset )
+/* Describe where in the type 'offset' falls. Caller must
+ deallocate the resulting XArray. */
+XArray* /*UChar*/ ML_(describe_type)( /*OUT*/OffT* residual_offset,
+ Type* ty, OffT offset )
{
XArray* xa = VG_(newXA)( ML_(dinfo_zalloc), ML_(dinfo_free),
sizeof(UChar) );
@@ -447,10 +450,7 @@
}
done:
- if (offset > 0) {
- copy_bytes_into_XA( xa, " +", 2 );
- copy_UWord_into_XA( xa, offset );
- }
+ *residual_offset = offset;
copy_bytes_into_XA( xa, "\0", 1 );
return xa;
}
Modified: branches/DATASYMS/include/pub_tool_debuginfo.h
===================================================================
--- branches/DATASYMS/include/pub_tool_debuginfo.h 2008-02-12 13:54:28 UTC (rev 7402)
+++ branches/DATASYMS/include/pub_tool_debuginfo.h 2008-02-12 20:18:11 UTC (rev 7403)
@@ -85,10 +85,12 @@
/* Try to form some description of data_addr by looking at the DWARF3
debug info we have. This considers all global variables, and all
frames in the stacks of all threads. Result (or as much as will
- fit) is put into into dname[0 .. n_dname-1] and is guaranteed to be
- zero terminated. */
-extern Bool VG_(get_data_description)( Addr data_addr,
- /*OUT*/Char* dname, Int n_dname );
+ fit) is put into into dname{1,2}[0 .. n_dname-1] and is guaranteed
+ to be zero terminated. */
+extern Bool VG_(get_data_description)( /*OUT*/Char* dname1,
+ /*OUT*/Char* dname2,
+ Int n_dname,
+ Addr data_addr );
/* Succeeds if the address is within a shared object or the main executable.
It doesn't matter if debug info is present or not. */
Modified: branches/DATASYMS/memcheck/mc_main.c
===================================================================
--- branches/DATASYMS/memcheck/mc_main.c 2008-02-12 13:54:28 UTC (rev 7402)
+++ branches/DATASYMS/memcheck/mc_main.c 2008-02-12 20:18:11 UTC (rev 7403)
@@ -2668,9 +2668,11 @@
OffT offset;
} DataSym;
- // Is described by Dwarf debug info. Arbitrary string.
+ // Is described by Dwarf debug info. Arbitrary strings. Must
+ // be the same length.
struct {
- Char descr[128];
+ Char descr1[96];
+ Char descr2[96];
} Variable;
// Could only narrow it down to be the PLT/GOT/etc of a given
@@ -2868,8 +2870,12 @@
break;
case Addr_Variable:
- VG_(message)(Vg_UserMsg,
- "%s%s%s", xpre, ai->Addr.Variable.descr, xpost);
+ if (ai->Addr.Variable.descr1[0] != '\0')
+ VG_(message)(Vg_UserMsg, "%s%s%s",
+ xpre, ai->Addr.Variable.descr1, xpost);
+ if (ai->Addr.Variable.descr2[0] != '\0')
+ VG_(message)(Vg_UserMsg, "%s%s%s",
+ xpre, ai->Addr.Variable.descr2, xpost);
break;
case Addr_SectKind:
@@ -3416,15 +3422,22 @@
}
}
/* Perhaps the variable type/location data describes it? */
- VG_(memset)( &ai->Addr.Variable.descr,
- 0, sizeof(ai->Addr.Variable.descr));
+ tl_assert(sizeof(ai->Addr.Variable.descr1)
+ == sizeof(ai->Addr.Variable.descr2));
+ VG_(memset)( &ai->Addr.Variable.descr1,
+ 0, sizeof(ai->Addr.Variable.descr1));
+ VG_(memset)( &ai->Addr.Variable.descr2,
+ 0, sizeof(ai->Addr.Variable.descr2));
if (VG_(get_data_description)(
- a,
- &ai->Addr.Variable.descr[0],
- sizeof(ai->Addr.Variable.descr)-1 )) {
+ &ai->Addr.Variable.descr1[0],
+ &ai->Addr.Variable.descr2[0],
+ sizeof(ai->Addr.Variable.descr1)-1,
+ a )) {
ai->tag = Addr_Variable;
- tl_assert( ai->Addr.Variable.descr
- [ sizeof(ai->Addr.Variable.descr)-1 ] == 0);
+ tl_assert( ai->Addr.Variable.descr1
+ [ sizeof(ai->Addr.Variable.descr1)-1 ] == 0);
+ tl_assert( ai->Addr.Variable.descr2
+ [ sizeof(ai->Addr.Variable.descr2)-1 ] == 0);
return;
}
/* Have a look at the low level data symbols - perhaps it's in
|