From: <sv...@va...> - 2008-02-28 18:03:52
|
Author: sewardj Date: 2008-02-28 18:03:49 +0000 (Thu, 28 Feb 2008) New Revision: 7498 Log: readdwarf3.c: don't be spooked by apparently-bogus DW_TAG_lexical_block created by icc9. debuginfo.c: try to handle obviously-bogus location expressions created by gcc-3.4.4 and gcc-3.4.5. Not sure if this is a good idea or not. Also, add more debug printing stuff. Modified: branches/DATASYMS/coregrind/m_debuginfo/d3basics.c branches/DATASYMS/coregrind/m_debuginfo/debuginfo.c branches/DATASYMS/coregrind/m_debuginfo/readdwarf3.c branches/DATASYMS/memcheck/tests/varinfo6.c Modified: branches/DATASYMS/coregrind/m_debuginfo/d3basics.c =================================================================== --- branches/DATASYMS/coregrind/m_debuginfo/d3basics.c 2008-02-28 08:30:43 UTC (rev 7497) +++ branches/DATASYMS/coregrind/m_debuginfo/d3basics.c 2008-02-28 18:03:49 UTC (rev 7498) @@ -630,6 +630,8 @@ aMax = * (Addr*)p; p += sizeof(Addr); nbytes = * (UShort*)p; p += sizeof(UShort); nGuards++; + if (0) VG_(printf)(" guard %d: %p %p\n", + (Int)nGuards, aMin,aMax); if (regs == NULL) { vg_assert(aMin == (Addr)0); vg_assert(aMax == ~(Addr)0); Modified: branches/DATASYMS/coregrind/m_debuginfo/debuginfo.c =================================================================== --- branches/DATASYMS/coregrind/m_debuginfo/debuginfo.c 2008-02-28 08:30:43 UTC (rev 7497) +++ branches/DATASYMS/coregrind/m_debuginfo/debuginfo.c 2008-02-28 18:03:49 UTC (rev 7498) @@ -1615,7 +1615,8 @@ var_szB = muw.w; if (show) { - VG_(printf)("VVVV: find loc: %s :: ", var->name ); + VG_(printf)("VVVV: data_address_%p_is_in_var: %s :: ", + data_addr, var->name ); ML_(pp_Type_C_ishly)( var->type ); VG_(printf)("\n"); } @@ -1812,11 +1813,13 @@ Word i; DebugInfo* di; RegSummary regs; + Bool debug = False; static UInt n_search = 0; static UInt n_steps = 0; n_search++; - if (0) VG_(printf)("QQQQ: cvif: ip,sp,fp %p,%p,%p\n", ip,sp,fp); + if (debug) + VG_(printf)("QQQQ: cvif: ip,sp,fp %p,%p,%p\n", ip,sp,fp); /* first, find the DebugInfo that pertains to 'ip'. */ for (di = debugInfo_list; di; di = di->next) { n_steps++; @@ -1868,7 +1871,8 @@ DiAddrRange* arange; OSet* this_scope = *(OSet**)VG_(indexXA)( di->varinfo, i ); - if (0) VG_(printf)("QQQQ: considering scope %ld\n", (Word)i); + if (debug) + VG_(printf)("QQQQ: considering scope %ld\n", (Word)i); if (!this_scope) continue; /* Find the set of variables in this scope that @@ -1898,6 +1902,9 @@ for (j = 0; j < VG_(sizeXA)( vars ); j++) { DiVariable* var = (DiVariable*)VG_(indexXA)( vars, j ); SizeT offset; + if (debug) + VG_(printf)("QQQQ: var:name=%s %p-%p %p\n", + var->name,arange->aMin,arange->aMax,ip); if (data_address_is_in_var( &offset, var, ®s, data_addr, di->data_bias )) { OffT residual_offset = 0; @@ -1939,7 +1946,6 @@ dname1[n_dname-1] = dname2[n_dname-1] = 0; if (0) VG_(printf)("get_data_description: dataaddr %p\n", data_addr); - /* First, see if data_addr is (or is part of) a global variable. Loop over the DebugInfos we have. Check data_addr against the outermost scope of all of them, as that should be a global @@ -2086,6 +2092,31 @@ dname1[n_dname-1] = dname2[n_dname-1] = 0; return True; } + /* Now, it appears that gcc sometimes appears to produce + location lists whose ranges don't actually cover the call + instruction, even though the address of the variable in + question is passed as a parameter in the call. AFAICS this + is simply a bug in gcc - how can the variable be claimed not + exist in memory (on the stack) for the duration of a call in + which its address is passed? But anyway, in the particular + case I investigated (memcheck/tests/varinfo6.c, call to croak + on line 2999, local var budget declared at line 3115 + appearing not to exist across the call to mainSort on line + 3143, "gcc.orig (GCC) 3.4.4 20050721 (Red Hat 3.4.4-2)" on + amd64), the variable's location list does claim it exists + starting at the first byte of the first instruction after the + call instruction. So, call consider_vars_in_frame a second + time, but this time don't subtract 1 from the IP. GDB + handles this example with no difficulty, which leads me to + believe that either (1) I misunderstood something, or (2) GDB + has an equivalent kludge. */ + if (consider_vars_in_frame( dname1, dname2, n_dname, + data_addr, + 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. */ Modified: branches/DATASYMS/coregrind/m_debuginfo/readdwarf3.c =================================================================== --- branches/DATASYMS/coregrind/m_debuginfo/readdwarf3.c 2008-02-28 08:30:43 UTC (rev 7497) +++ branches/DATASYMS/coregrind/m_debuginfo/readdwarf3.c 2008-02-28 18:03:49 UTC (rev 7498) @@ -1462,6 +1462,21 @@ rangeoff, cc->cu_svma ), level, isFunc, fbGX ); } else + if (have_lo && (!have_hi1) && (!have_range)) { + /* This scope is bogus. The D3 spec sec 3.4 (Lexical Block + Entries) says fairly clearly that a scope must have either + _range or (_low_pc and _high_pc). */ + /* The spec is a bit ambiguous though. Perhaps a single byte + range is intended? See sec 2.17 (Code Addresses And Ranges) */ + /* This case is here because icc9 produced this: + <2><13bd>: DW_TAG_lexical_block + DW_AT_decl_line : 5229 + DW_AT_decl_column : 37 + DW_AT_decl_file : 1 + DW_AT_low_pc : 0x401b03 + */ + /* Ignore (seems safe than pushing a single byte range) */ + } else goto bad_DIE; } Modified: branches/DATASYMS/memcheck/tests/varinfo6.c =================================================================== --- branches/DATASYMS/memcheck/tests/varinfo6.c 2008-02-28 08:30:43 UTC (rev 7497) +++ branches/DATASYMS/memcheck/tests/varinfo6.c 2008-02-28 18:03:49 UTC (rev 7498) @@ -2996,7 +2996,7 @@ for (j = ftab[ss << 8] & CLEARMASK; j < copyStart[ss]; j++) { k = ptr[j]-1; if (k < 0) k += nblock; c1 = block[k]; -croak( 2 + (char*)budget ); +croak( 2 + (char*)budget ); /* should identify decl in calling frame */ if (!bigDone[c1]) ptr[ copyStart[c1]++ ] = k; } |