From: Andrew Burgess <andrew.burgess@embecosm.com>
To: Simon Marchi <simon.marchi@polymtl.ca>
Cc: gdb-patches@sourceware.org
Subject: Re: [PATCH master + gdb-10-branch] gdb: fix getting range of flexible array member in Python
Date: Thu, 22 Apr 2021 17:48:30 +0100 [thread overview]
Message-ID: <20210422164830.GQ2610@embecosm.com> (raw)
In-Reply-To: <20210422155950.3520038-1-simon.marchi@polymtl.ca>
* Simon Marchi via Gdb-patches <gdb-patches@sourceware.org> [2021-04-22 11:59:50 -0400]:
> As reported in bug 27757, we get an internal error when doing:
>
> $ cat test.c
> struct foo {
> int len;
> int items[];
> };
>
> struct foo *p;
>
> int main() {
> return 0;
> }
> $ gcc test.c -g -O0 -o test
> $ ./gdb -q -nx --data-directory=data-directory ./test -ex 'python gdb.parse_and_eval("p").type.target()["items"].type.range()'
> Reading symbols from ./test...
> /home/simark/src/binutils-gdb/gdb/gdbtypes.h:435: internal-error: LONGEST dynamic_prop::const_val() const: Assertion `m_kind == PROP_CONST' failed.
> A problem internal to GDB has been detected,
> further debugging may prove unreliable.
> Quit this debugging session? (y or n)
>
> This is because the Python code (typy_range) blindly reads the high
> bound of the type of `items` as a constant value. Since it is a
> flexible array member, it has no high bound, the property is undefined.
> Since commit 8c2e4e0689 ("gdb: add accessors to struct dynamic_prop"),
> the getters check that you are not getting a property value of the wrong
> kind, so this causes a failed assertion.
>
> Fix it by checking if the property is indeed a constant value before
> accessing it as such. Otherwise, use 0. This restores the previous GDB
> behavior: because the structure was zero-initialized, this is what was
> returned before. But now this behavior is explicit and not accidental.
>
> Add a test, gdb.python/flexible-array-member.exp, that is derived from
> gdb.base/flexible-array-member.exp. It tests the same things, but
> through the Python API. It also specifically tests getting the range
> from the various kinds of flexible array member types (AFAIK it wasn't
> possible to do the equivalent through the CLI).
>
> gdb/ChangeLog:
>
> PR gdb/27757
> * python/py-type.c (typy_range): Check that bounds are constant
> before accessing them as such.
>
> gdb/testsuite/ChangeLog:
>
> PR gdb/27757
> * gdb.python/flexible-array-member.c: New test.
> * gdb.python/flexible-array-member.exp: New test.
>
> Change-Id: Ibef92ee5fd871ecb7c791db2a788f203dff2b841
> ---
> gdb/python/py-type.c | 11 ++-
> .../gdb.python/flexible-array-member.c | 70 ++++++++++++++++
> .../gdb.python/flexible-array-member.exp | 81 +++++++++++++++++++
> 3 files changed, 160 insertions(+), 2 deletions(-)
> create mode 100644 gdb/testsuite/gdb.python/flexible-array-member.c
> create mode 100644 gdb/testsuite/gdb.python/flexible-array-member.exp
>
> diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c
> index bf707078841f..148e4a6aa3a0 100644
> --- a/gdb/python/py-type.c
> +++ b/gdb/python/py-type.c
> @@ -592,8 +592,15 @@ typy_range (PyObject *self, PyObject *args)
> case TYPE_CODE_ARRAY:
> case TYPE_CODE_STRING:
> case TYPE_CODE_RANGE:
> - low = type->bounds ()->low.const_val ();
> - high = type->bounds ()->high.const_val ();;
I think the same bug exists in guile/scm-type.c, even if we don't add
a test it is probably worth duplicating the fix there too.
Also I wonder if, now we have defined this behaviour, should we add
this to the docs?
Thanks,
Andrew
> + if (type->bounds ()->low.kind () == PROP_CONST)
> + low = type->bounds ()->low.const_val ();
> + else
> + low = 0;
> +
> + if (type->bounds ()->high.kind () == PROP_CONST)
> + high = type->bounds ()->high.const_val ();
> + else
> + high = 0;
> break;
> }
>
> diff --git a/gdb/testsuite/gdb.python/flexible-array-member.c b/gdb/testsuite/gdb.python/flexible-array-member.c
> new file mode 100644
> index 000000000000..79815e2d38e0
> --- /dev/null
> +++ b/gdb/testsuite/gdb.python/flexible-array-member.c
> @@ -0,0 +1,70 @@
> +/* This testcase is part of GDB, the GNU debugger.
> +
> + Copyright 2020-2021 Free Software Foundation, Inc.
> +
> + This program is free software; you can redistribute it and/or modify
> + it under the terms of the GNU General Public License as published by
> + the Free Software Foundation; either version 3 of the License, or
> + (at your option) any later version.
> +
> + This program is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + GNU General Public License for more details.
> +
> + You should have received a copy of the GNU General Public License
> + along with this program. If not, see <http://www.gnu.org/licenses/>. */
> +
> +#include <stdlib.h>
> +
> +struct no_size
> +{
> + int n;
> + int items[];
> +};
> +
> +struct zero_size
> +{
> + int n;
> + int items[0];
> +};
> +
> +struct zero_size_only
> +{
> + int items[0];
> +};
> +
> +struct no_size *ns;
> +struct zero_size *zs;
> +struct zero_size_only *zso;
> +
> +static void
> +break_here (void)
> +{
> +}
> +
> +int
> +main (void)
> +{
> + ns = (struct no_size *) malloc (sizeof (*ns) + 3 * sizeof (int));
> + zs = (struct zero_size *) malloc (sizeof (*zs) + 3 * sizeof (int));
> + zso = (struct zero_size_only *) malloc (sizeof (*zso) + 3 * sizeof (int));
> +
> + ns->n = 3;
> + ns->items[0] = 101;
> + ns->items[1] = 102;
> + ns->items[2] = 103;
> +
> + zs->n = 3;
> + zs->items[0] = 201;
> + zs->items[1] = 202;
> + zs->items[2] = 203;
> +
> + zso->items[0] = 301;
> + zso->items[1] = 302;
> + zso->items[2] = 303;
> +
> + break_here ();
> +
> + return 0;
> +}
> diff --git a/gdb/testsuite/gdb.python/flexible-array-member.exp b/gdb/testsuite/gdb.python/flexible-array-member.exp
> new file mode 100644
> index 000000000000..3739c9a9e5c0
> --- /dev/null
> +++ b/gdb/testsuite/gdb.python/flexible-array-member.exp
> @@ -0,0 +1,81 @@
> +# Copyright 2020-2021 Free Software Foundation, Inc.
> +
> +# This program is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 3 of the License, or
> +# (at your option) any later version.
> +#
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with this program. If not, see <http://www.gnu.org/licenses/>.
> +
> +# Test getting the range of flexible array members in Python.
> +
> +standard_testfile
> +
> +if { [prepare_for_testing "failed to prepare" \
> + ${testfile} ${srcfile}] } {
> + return
> +}
> +
> +if { ![runto break_here] } {
> + untested "could not run to break_here"
> + return
> +}
> +
> +# The various cases are:
> +#
> +# - ns: flexible array member with no size
> +# - zs: flexible array member with size 0 (GNU C extension that predates the
> +# standardization of the feature, but widely supported)
> +# - zso: zero-size only, a corner case where the array is the sole member of
> +# the structure
> +
> +gdb_test "python ns = gdb.parse_and_eval('ns').dereference()"
> +gdb_test "python zs = gdb.parse_and_eval('zs').dereference()"
> +gdb_test "python zso = gdb.parse_and_eval('zso').dereference()"
> +
> +# Print the whole structure.
> +
> +gdb_test "python print(ns)" "{n = 3, items = $hex}"
> +gdb_test "python print(zs)" "{n = 3, items = $hex}"
> +gdb_test "python print(zso)" "{items = $hex}"
> +
> +# Print all items.
> +
> +gdb_test "python print(ns\['items'\])" "$hex"
> +gdb_test "python print(ns\['items'\]\[0\])" "101"
> +gdb_test "python print(ns\['items'\]\[1\])" "102"
> +gdb_test "python print(ns\['items'\]\[2\])" "103"
> +
> +gdb_test "python print(zs\['items'\])" "$hex"
> +gdb_test "python print(zs\['items'\]\[0\])" "201"
> +gdb_test "python print(zs\['items'\]\[1\])" "202"
> +gdb_test "python print(zs\['items'\]\[2\])" "203"
> +
> +gdb_test "python print(zso\['items'\])" "$hex"
> +gdb_test "python print(zso\['items'\]\[0\])" "301"
> +gdb_test "python print(zso\['items'\]\[1\])" "302"
> +gdb_test "python print(zso\['items'\]\[2\])" "303"
> +
> +# Check taking the address of array elements (how PR 28675 was originally
> +# reported).
> +
> +gdb_test "python print(ns\['items'\] == ns\['items'\]\[0\].address)" "True"
> +gdb_test "python print(ns\['items'\]\[0\].address + 1 == ns\['items'\]\[1\].address)" "True"
> +gdb_test "python print(zs\['items'\] == zs\['items'\]\[0\].address)" "True"
> +gdb_test "python print(zs\['items'\]\[0\].address + 1 == zs\['items'\]\[1\].address)" "True"
> +gdb_test "python print(zso\['items'\] == zso\['items'\]\[0\].address)" "True"
> +gdb_test "python print(zso\['items'\]\[0\].address + 1 == zso\['items'\]\[1\].address)" "True"
> +
> +# Verify the range attribute. It looks a bit inconsistent that the high bound
> +# is sometimes 0, sometimes -1, but that's what GDB produces today, so that's
> +# what we test.
> +
> +gdb_test "python print(ns\['items'\].type.range())" "\\(0, 0\\)"
> +gdb_test "python print(zs\['items'\].type.range())" "\\(0, -1\\)"
> +gdb_test "python print(zso\['items'\].type.range())" "\\(0, -1\\)"
> --
> 2.30.1
>
next prev parent reply other threads:[~2021-04-22 16:48 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-04-22 15:59 Simon Marchi via Gdb-patches
2021-04-22 16:48 ` Andrew Burgess [this message]
2021-04-22 17:19 ` Simon Marchi via Gdb-patches
2021-04-22 17:50 ` Andrew Burgess
2021-04-22 19:07 ` Simon Marchi via Gdb-patches
2021-04-22 19:40 ` Luis Machado via Gdb-patches
2021-04-22 19:47 ` Simon Marchi via Gdb-patches
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210422164830.GQ2610@embecosm.com \
--to=andrew.burgess@embecosm.com \
--cc=gdb-patches@sourceware.org \
--cc=simon.marchi@polymtl.ca \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox