From: Philippe Waroquiers Date: Wed, 13 Sep 2017 20:47:11 +0000 (+0200) Subject: Fix Bug 255603 - exp-sgcheck Assertion '!already_present' failed X-Git-Tag: VALGRIND_3_14_0~262 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=621cde90f7d23e916d3ce2716df02d261a72f5f3;p=thirdparty%2Fvalgrind.git Fix Bug 255603 - exp-sgcheck Assertion '!already_present' failed 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. --- diff --git a/NEWS b/NEWS index e43410acb6..e910b7f669 100644 --- 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) diff --git a/coregrind/m_debuginfo/readdwarf3.c b/coregrind/m_debuginfo/readdwarf3.c index 4d8f21b326..2f538c9e4d 100644 --- a/coregrind/m_debuginfo/readdwarf3.c +++ b/coregrind/m_debuginfo/readdwarf3.c @@ -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; }