]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Fix Bug 255603 - exp-sgcheck Assertion '!already_present' failed
authorPhilippe Waroquiers <philippe.waroquiers@skynet.be>
Wed, 13 Sep 2017 20:47:11 +0000 (22:47 +0200)
committerPhilippe Waroquiers <philippe.waroquiers@skynet.be>
Wed, 13 Sep 2017 20:47:11 +0000 (22:47 +0200)
The code handling array bounds is not ready to accept a reference
to something else (not very clear what this reference could be) :
the code only expects directly the value of a bound.
So, it was using the reference (i.e. an offset somewehere in the debug
info) as the value of the bound.
This then gave huge bounds for some arrays, causing an overlap
in the stack variable handling code in exp-sgcheck.

Such references seems to be used sometimes for arrays with variable
size stack allocated.

Fix (or rather bypass) the problem by not considering that we have
a usable array bound when a reference is given.

NEWS
coregrind/m_debuginfo/readdwarf3.c

diff --git a/NEWS b/NEWS
index e43410acb67908833d2f1d078ad09ca59c17ee4b..e910b7f66967eee9f3de1fe151ce86b66ee3c6b5 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -35,6 +35,7 @@ To see details of a given bug, visit
   https://bugs.kde.org/show_bug.cgi?id=XXXXXX
 where XXXXXX is the bug number as listed below.
 
+255603  exp-sgcheck Assertion '!already_present' failed
 379373  Fix syscall param msg->desc.port.name points to uninitialised byte(s)
         on macOS 10.12
 379748  Fix missing pselect syscall (OS X 10.11)
index 4d8f21b326d90488c3b9b21e282f2fd2d8eb487a..2f538c9e4d4ff7bd6b5ce5d0bf0fa062e13e8e4f 100644 (file)
@@ -2993,6 +2993,20 @@ static Bool subrange_type_denotes_array_bounds ( const D3TypeParser* parser,
               && parser->qparentE[parser->sp].tag == Te_TyArray);
 }
 
+/* True if the form is one of the forms supported to give an array bound.
+   For some arrays (scope local arrays with variable size), 
+   a DW_FORM_ref4 was used, and was wrongly used as the bound value.
+   So, refuse the forms that are known to give a problem. */
+static Bool form_expected_for_bound ( DW_FORM form ) {
+   if (form == DW_FORM_ref1 
+       || form == DW_FORM_ref2
+       || form == DW_FORM_ref4
+       || form == DW_FORM_ref8)
+      return False;
+
+   return True;
+}
+
 /* Parse a type-related DIE.  'parser' holds the current parser state.
    'admin' is where the completed types are dumped.  'dtag' is the tag
    for this DIE.  'c_die' points to the start of the data fields (FORM
@@ -3598,11 +3612,13 @@ static void parse_type_DIE ( /*MOD*/XArray* /* of TyEnt */ tyents,
          nf_i++;
          if (attr == 0 && form == 0) break;
          get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
-         if (attr == DW_AT_lower_bound && cts.szB > 0) {
+         if (attr == DW_AT_lower_bound && cts.szB > 0 
+             && form_expected_for_bound (form)) {
             lower      = (Long)cts.u.val;
             have_lower = True;
          }
-         if (attr == DW_AT_upper_bound && cts.szB > 0) {
+         if (attr == DW_AT_upper_bound && cts.szB > 0 
+             && form_expected_for_bound (form)) {
             upper      = (Long)cts.u.val;
             have_upper = True;
          }