From patchwork Wed Aug 1 21:12:52 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Burgess X-Patchwork-Id: 28720 Received: (qmail 26880 invoked by alias); 1 Aug 2018 21:13:04 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 26734 invoked by uid 89); 1 Aug 2018 21:13:03 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-25.8 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=_any_ X-HELO: mail-wm0-f51.google.com Received: from mail-wm0-f51.google.com (HELO mail-wm0-f51.google.com) (74.125.82.51) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 01 Aug 2018 21:13:01 +0000 Received: by mail-wm0-f51.google.com with SMTP id y9-v6so128174wma.5 for ; Wed, 01 Aug 2018 14:13:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=embecosm.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=G032F4umKDq51Oi7PMnEemk60TjLTmIsCA1D07Z1nbI=; b=AzzK9YuKNzdG8mkSVuR09MW32y1x1tkAnHo5TqRGFtfUJ7BCx4V9H0uRy+W8bSQ6fc smeoA3eGz3peuP/Lup5YIIyQZ8o8iCEKpSaouaaqk2ICsef9G10D4chD/qxOqs0NTjSt muwTQDco4/fXn6894rTaOo0Xdwh8ALq4xHgL2BJpb0ND/siLLI8ZwmVXMGkT9oY7efjI BCa36vLoflt/gRST2XOGLToJKqaOTJxIyNRq3zDlZ/tf/k5NcpuKA3ky8wAZREpc3HSN KPtRgqpKate34Gm6TBdFpmmmX8RO9LAKsL/9Ff9tEfzvYmwSvI2q9mEqqp+XdKmbVju9 NyrA== Return-Path: Received: from localhost (host109-147-66-79.range109-147.btcentralplus.com. [109.147.66.79]) by smtp.gmail.com with ESMTPSA id z141-v6sm193779wmc.3.2018.08.01.14.12.58 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 01 Aug 2018 14:12:58 -0700 (PDT) From: Andrew Burgess To: gdb-patches@sourceware.org Cc: Andrew Burgess Subject: [PATCH 2/2] gdb: Check element of optimised out vla exists Date: Wed, 1 Aug 2018 22:12:52 +0100 Message-Id: <8e9a61d7fd387de60ea454bd4a308ecef1a0c45d.1533157680.git.andrew.burgess@embecosm.com> In-Reply-To: References: In-Reply-To: References: X-IsSubscribed: yes The new tests cover accessing an element that should exist in the VLA (except it has been optimised out), accessing just beyond the VLA, and accessing far beyond the VLA. The third test is included as this might cause GDB to crash without the fix (though undefined behaviour, so, you never know). I did have a patch that added an assertion and caught the rogue access, however, it turns out the assertion triggers from our extension language pretty-printer code so I've had to drop the assertion for now while I work on fixing that. Thanks, Andrew --- If a vla is not in memory, and the upper bound is not defined, then we can't know that an array element exists or not, and we should not try to access the array element. One case where this happens is for arrays that have been optimised out, the array will then have VALUE_LVAL of not_lval, and an undefined upper bound, if we then try to access an element of this array we will index into random GDB memory. An argument could be made that even for arrays that are in inferior memory, if the upper bound is not defined then we should not try to access the array element, however, in some of the Fortran tests, it seems as though we do rely indexing from a base address into an array which has no bounds defined. In this case GDBs standard protection for detecting unreadable target memory prevents bad thing happening. gdb/ChangeLog: * valarith.c (value_subscripted_rvalue): If an array is not in memory, and we don't know the upper bound, then we can't know that the requested element exists or not. gdb/testsuite/ChangeLog: * gdb.base/vla-optimized-out.exp: Add new test. --- gdb/ChangeLog | 6 ++++++ gdb/testsuite/ChangeLog | 4 ++++ gdb/testsuite/gdb.base/vla-optimized-out.exp | 22 ++++++++++++++++++++++ gdb/valarith.c | 7 +++++-- 4 files changed, 37 insertions(+), 2 deletions(-) diff --git a/gdb/testsuite/gdb.base/vla-optimized-out.exp b/gdb/testsuite/gdb.base/vla-optimized-out.exp index fa521765969..ed9f269b5f3 100644 --- a/gdb/testsuite/gdb.base/vla-optimized-out.exp +++ b/gdb/testsuite/gdb.base/vla-optimized-out.exp @@ -37,6 +37,28 @@ proc vla_optimized_out {compile_flags exe_suffix sizeof_result} { gdb_test "p sizeof (a)" \ " = $sizeof_result" \ "printed size of optimized out vla" + + # At lower optimisation levels, the upper bound of the array is + # still defined, it's just the loctaion that tells GDB the array + # is optimised out. In that case, when we access an element that + # is within the bounds of the array an answer of '' + # is reasonable. + # + # At higher optimisation levels, the array bounds themselves have + # been removed. As such GDB can't be expected to know if the + # array contains _any_ elements at all. It seems reasonable in + # that case to reply with 'no such vector element'. + gdb_test "p a\[0\]" \ + "(= |no such vector element)" \ + "print out of range element of vla (0)" + + gdb_test "p a\[6\]" \ + "no such vector element" \ + "print out of range element of vla (6)" + + gdb_test "p a\[0xffffffff\]" \ + "no such vector element" \ + "print out of range element of vla (0xffffffff)" } foreach test_settings [list \ diff --git a/gdb/valarith.c b/gdb/valarith.c index 01ca50d3d21..807cdd5dbd4 100644 --- a/gdb/valarith.c +++ b/gdb/valarith.c @@ -189,8 +189,11 @@ value_subscripted_rvalue (struct value *array, LONGEST index, int lowerbound) ULONGEST elt_size = type_length_units (elt_type); ULONGEST elt_offs = elt_size * (index - lowerbound); - if (index < lowerbound || (!TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED (array_type) - && elt_offs >= type_length_units (array_type))) + if (index < lowerbound + || (!TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED (array_type) + && elt_offs >= type_length_units (array_type)) + || (VALUE_LVAL (array) != lval_memory + && TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED (array_type))) { if (type_not_associated (array_type)) error (_("no such vector element (vector not associated)"));