]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
On a big application linking with gtk, using the compilation options
authorPhilippe Waroquiers <philippe.waroquiers@skynet.be>
Wed, 7 May 2014 21:09:16 +0000 (21:09 +0000)
committerPhilippe Waroquiers <philippe.waroquiers@skynet.be>
Wed, 7 May 2014 21:09:16 +0000 (21:09 +0000)
-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

NEWS
coregrind/m_debuginfo/readdwarf3.c

diff --git a/NEWS b/NEWS
index 8accb8d0c1285137d4153102897952101c89688e..ac02d09d2e4f0339f076a42a769b6c8957f0c138 100644 (file)
--- 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 ====================
 
index 0052d334856d1fa42cc19863c5a8be5657f21b9c..de491e93a1d54306004be4282ab05b98a13d3f07 100644 (file)
@@ -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,