aboutsummaryrefslogtreecommitdiff
path: root/gdb/testsuite/gdb.guile
diff options
context:
space:
mode:
authorSimon Marchi <simon.marchi@polymtl.ca>2021-04-22 15:01:28 -0400
committerSimon Marchi <simon.marchi@polymtl.ca>2021-04-22 15:01:28 -0400
commite25d6d93c4a0d597da2521c2c38cb1ce6e51feb8 (patch)
treea969eadcbae435fade7ceaf03a5816cf1385cc4c /gdb/testsuite/gdb.guile
parent2f63213381e3b073f169ee776043486b44ea2e68 (diff)
downloadgdb-e25d6d93c4a0d597da2521c2c38cb1ce6e51feb8.zip
gdb-e25d6d93c4a0d597da2521c2c38cb1ce6e51feb8.tar.gz
gdb-e25d6d93c4a0d597da2521c2c38cb1ce6e51feb8.tar.bz2
gdb: fix getting range of flexible array member in Python
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
Diffstat (limited to 'gdb/testsuite/gdb.guile')
-rw-r--r--gdb/testsuite/gdb.guile/scm-type.c12
-rw-r--r--gdb/testsuite/gdb.guile/scm-type.exp12
2 files changed, 24 insertions, 0 deletions
diff --git a/gdb/testsuite/gdb.guile/scm-type.c b/gdb/testsuite/gdb.guile/scm-type.c
index 782b8fe..64f5f02 100644
--- a/gdb/testsuite/gdb.guile/scm-type.c
+++ b/gdb/testsuite/gdb.guile/scm-type.c
@@ -15,6 +15,8 @@
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 s
{
int a;
@@ -53,6 +55,12 @@ enum E
struct s vec_data_1 = {1, 1};
struct s vec_data_2 = {1, 2};
+struct flex_member
+{
+ int n;
+ int items[];
+};
+
int
main ()
{
@@ -72,6 +80,10 @@ main ()
st.b = 5;
e = v2;
+
+ struct flex_member *f = (struct flex_member *) malloc (100);
+ f->items[0] = 111;
+ f->items[1] = 222;
return 0; /* break to inspect struct and array. */
}
diff --git a/gdb/testsuite/gdb.guile/scm-type.exp b/gdb/testsuite/gdb.guile/scm-type.exp
index 8778cdb..517c99f 100644
--- a/gdb/testsuite/gdb.guile/scm-type.exp
+++ b/gdb/testsuite/gdb.guile/scm-type.exp
@@ -261,6 +261,18 @@ proc test_range {} {
"ERROR: .*: Wrong type argument in position 1 \\(expecting ranged type\\): .*" \
"check range for non ranged type"
}
+
+ with_test_prefix "on flexible array member" {
+ gdb_scm_test_silent_cmd "print f" "print value (f)"
+ gdb_scm_test_silent_cmd "guile (define f (history-ref 0))" \
+ "get value (f) from history"
+ gdb_test "guile (print (type-range (field-type (type-field (value-type (value-dereference f)) \"items\"))))" \
+ "= \\(0 0\\)"
+ gdb_test "guile (print (value-subscript (value-field (value-dereference f) \"items\") 0))" \
+ "= 111"
+ gdb_test "guile (print (value-subscript (value-field (value-dereference f) \"items\") 1))" \
+ "= 222"
+ }
}
}