From: Philippe Waroquiers Date: Wed, 7 May 2014 21:09:16 +0000 (+0000) Subject: On a big application linking with gtk, using the compilation options X-Git-Tag: svn/VALGRIND_3_10_0~495 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=55c12b3a188146979cc72caa8f7ef886cd0faf34;p=thirdparty%2Fvalgrind.git On a big application linking with gtk, using the compilation options -ffunction-sections -fdata-sections and the linker option -Wl,--gc-sections, --read-var-info=yes gives the following: valgrind: m_debuginfo/d3basics.c:973 (vgModuleLocal_evaluate_GX): Assertion 'aMax == ~(Addr)0' failed. host stacktrace: ==18521== at 0x38057C54: show_sched_status_wrk (m_libcassert.c:308) ==18521== by 0x38057F50: report_and_quit (m_libcassert.c:367) ==18521== by 0x38058151: vgPlain_assert_fail (m_libcassert.c:432) ==18521== by 0x3813F084: vgModuleLocal_evaluate_GX (d3basics.c:973) ==18521== by 0x38098300: data_address_is_in_var (debuginfo.c:2769) ==18521== by 0x38099E26: vgPlain_get_data_description (debuginfo.c:3298) ... The problem is that -Wl,--gc-sections eliminates the unused functions but keeps some debug info for the functions or their compilation units. The dwarf entry has low and high pc, but both are equal to 0. The dwarf reader of Valgrind is confused by this, as the varstack becomes empty, while it should not. This then causes local (eliminated) variables to be put in the global scope, leading afterwards to evaluation errors when describing any other variables. The fix is to also push something on the varstack when a CU that has low and high pc given but with 0 value. This is similar to the varstack_push done for a CU that has no low pc, no high pc and no range. Despite considerable effort to make a small reproducer, the problem could only be produced with a big executable. After the fix, everything was working properly. The wrong behaviour for dwarf entries produce the following trace: <2><2ff291a>: Abbrev Number: 23 (DW_TAG_formal_parameter) DW_AT_name : AET DW_AT_decl_file : 1 DW_AT_decl_line : 243 DW_AT_type : <2ff2811> DW_AT_location : 18288554 Recording this variable, with 1 PC range(s) .... <2ff291a> addVar: level 0: AET :: EdgeTableEntry* Loc=GX(final){[0x0,0x8]=50,[0x9,0x1d]=53,[0x1e,0x26]=51,[0x27,0x29]=53,[0x2a,0x2f]=51,[0x44,0x4a]=53,[0x4d,0x5e]=51,[0x5f,0x62]=53} FrB=none declared at: gdkpolyreg-generic.c:243 ACQUIRE for range(s) [0x0,0xffffffff] The AET is a formal parameter of a function, but is wrongly added at level 0, with a PC range covering the full space. It has a Loc GX which uses non biased program counters (e.g. 0x0,0x8). This dwarf entry will require a FrB (and registers when evaluating) but no such things are available (or given) when evaluating a variable in the global scope. The fix is to handle compilation units with lo and hi pc == 0x0 similarly to a CU that has no lo and hi pc. With this fix, valgrind --read-var-info=yes could properly handle a big application with plenty of eliminated functions. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@13941 --- diff --git a/NEWS b/NEWS index 8accb8d0c1..ac02d09d2e 100644 --- a/NEWS +++ b/NEWS @@ -44,8 +44,10 @@ Release 3.10.0 (?? ?????? 201?) by increasing the value. See user manual for details. -* Support for --read-var-info=yes has been improved - to handle Ada and C struct containing VLA. +* Minor improvements in dwarf handling with --read-var-info=yes + - Ada and C struct containing VLA do not cause a bad DIE error anymore + - Code compiled with -ffunction-sections -fdata-sections -Wl,--gc-sections + does not cause assert errors anymore. * ==================== FIXED BUGS ==================== diff --git a/coregrind/m_debuginfo/readdwarf3.c b/coregrind/m_debuginfo/readdwarf3.c index 0052d33485..de491e93a1 100644 --- a/coregrind/m_debuginfo/readdwarf3.c +++ b/coregrind/m_debuginfo/readdwarf3.c @@ -1749,6 +1749,18 @@ static void parse_var_DIE ( unitary_range_list(ip_lo, ip_hi1 - 1), level, False/*isFunc*/, NULL/*fbGX*/ ); + else if (ip_lo == 0 && ip_hi1 == 0) + /* CU has no code, presumably? + Such situations have been encountered for code + compiled with -ffunction-sections -fdata-sections + and linked with --gc-sections. Completely + eliminated CU gives such 0 lo/hi pc. Similarly + to a CU which has no lo/hi/range pc, we push + an empty range list. */ + varstack_push( cc, parser, td3, + empty_range_list(), + level, + False/*isFunc*/, NULL/*fbGX*/ ); } else if ((!have_lo) && (!have_hi1) && have_range) { varstack_push( cc, parser, td3,