
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.
* guile/scm-type.c (gdbscm_type_range): Likewise.
gdb/testsuite/ChangeLog:
PR gdb/27757
* gdb.python/flexible-array-member.c: New test.
* gdb.python/flexible-array-member.exp: New test.
* gdb.guile/scm-type.exp (test_range): Add test for flexible
array member.
* gdb.guile/scm-type.c (struct flex_member): New.
(main): Use it.
Change-Id: Ibef92ee5fd871ecb7c791db2a788f203dff2b841
70 lines
1.5 KiB
C
70 lines
1.5 KiB
C
/* 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;
|
|
}
|