* [RFA] Fix crash of convenience vars with typedefs.
@ 2009-08-15 0:22 Doug Evans
2009-08-17 13:11 ` Ulrich Weigand
0 siblings, 1 reply; 7+ messages in thread
From: Doug Evans @ 2009-08-15 0:22 UTC (permalink / raw)
To: uweigand, gdb-patches
Hi.
gdb crashes with the attached testcase.
gdb/value.c:1094: internal-error: bad type
A problem internal to GDB has been detected,
further debugging may prove unreliable.
value_of_internalvar needs to run the type through check_typedef.
I think this is a reasonable fix.
Ok to check in?
2009-08-14 Doug Evans <dje@google.com>
* value.c (value_of_internalvar): Handle typedefs in scalar values.
* gdb.base/gdbvars.c: New file.
* gdb.base/gdbvars.exp: Test convenience vars with program variables.
Index: value.c
===================================================================
RCS file: /cvs/src/src/gdb/value.c,v
retrieving revision 1.92
diff -u -p -r1.92 value.c
--- value.c 13 Aug 2009 18:39:20 -0000 1.92
+++ value.c 14 Aug 2009 23:58:45 -0000
@@ -1086,12 +1086,22 @@ value_of_internalvar (struct gdbarch *gd
if (!var->u.scalar.type)
val = value_from_longest (builtin_type (gdbarch)->builtin_int,
var->u.scalar.val.l);
- else if (TYPE_CODE (var->u.scalar.type) == TYPE_CODE_INT)
- val = value_from_longest (var->u.scalar.type, var->u.scalar.val.l);
- else if (TYPE_CODE (var->u.scalar.type) == TYPE_CODE_PTR)
- val = value_from_pointer (var->u.scalar.type, var->u.scalar.val.a);
else
- internal_error (__FILE__, __LINE__, "bad type");
+ {
+ struct type *real_type = check_typedef (var->u.scalar.type);
+ switch (TYPE_CODE (check_typedef (real_type)))
+ {
+ case TYPE_CODE_INT:
+ val = value_from_longest (real_type, var->u.scalar.val.l);
+ break;
+ case TYPE_CODE_PTR:
+ val = value_from_pointer (real_type, var->u.scalar.val.a);
+ break;
+ default:
+ internal_error (__FILE__, __LINE__, "bad type");
+ break;
+ }
+ }
break;
case INTERNALVAR_STRING:
Index: testsuite/gdb.base/gdbvars.c
===================================================================
RCS file: testsuite/gdb.base/gdbvars.c
diff -N testsuite/gdb.base/gdbvars.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.base/gdbvars.c 14 Aug 2009 23:58:45 -0000
@@ -0,0 +1,16 @@
+/* Simple program to help exercise gdb's convenience variables. */
+
+typedef void *ptr;
+
+ptr p = &p;
+
+int
+main ()
+{
+#ifdef usestubs
+ set_debug_traps ();
+ breakpoint ();
+#endif
+
+ return 0;
+}
Index: testsuite/gdb.base/gdbvars.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.base/gdbvars.exp,v
retrieving revision 1.6
diff -u -p -r1.6 gdbvars.exp
--- testsuite/gdb.base/gdbvars.exp 3 Jan 2009 05:58:03 -0000 1.6
+++ testsuite/gdb.base/gdbvars.exp 14 Aug 2009 23:58:45 -0000
@@ -22,6 +22,15 @@ if $tracelevel then {
set prms_id 0
set bug_id 0
+set testfile "gdbvars"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ untested gdbvars.exp
+ return -1
+}
+
proc test_convenience_variables {} {
global gdb_prompt
@@ -101,13 +110,23 @@ proc test_value_history {} {
"Use value-history element in arithmetic expression"
}
+proc test_with_program {} {
+ global hex
+ gdb_test "set \$prog_var = p" "" \
+ "Set a new convenience variable to a program variable"
+ gdb_test "print /x \$prog_var" " = $hex" \
+ "Print contents of new convenience variable of program variable"
+}
+
# Start with a fresh gdb.
gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
send_gdb "set print sevenbit-strings\n" ; gdb_expect -re ".*$gdb_prompt $"
test_value_history
test_convenience_variables
+test_with_program
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [RFA] Fix crash of convenience vars with typedefs. 2009-08-15 0:22 [RFA] Fix crash of convenience vars with typedefs Doug Evans @ 2009-08-17 13:11 ` Ulrich Weigand 2009-08-17 16:10 ` Tom Tromey 2009-08-17 18:22 ` Ulrich Weigand 0 siblings, 2 replies; 7+ messages in thread From: Ulrich Weigand @ 2009-08-17 13:11 UTC (permalink / raw) To: Doug Evans; +Cc: gdb-patches Doug Evans wrote: > gdb/value.c:1094: internal-error: bad type > A problem internal to GDB has been detected, > further debugging may prove unreliable. Oops, sorry for the breakage. > + struct type *real_type = check_typedef (var->u.scalar.type); > + switch (TYPE_CODE (check_typedef (real_type))) That's a duplicate check_typedef ... > + case TYPE_CODE_INT: > + val = value_from_longest (real_type, var->u.scalar.val.l); > + break; > + case TYPE_CODE_PTR: > + val = value_from_pointer (real_type, var->u.scalar.val.a); > + break; Shouldn't the result of value_of_internalvar still have the original typedef name instead of the type it resolves to? I'm wondering about the other places where the type is used, in particular get_internalvar_integer. Also, it seems better to avoid calling check_typedef every time ... Maybe it would be best to split the INTERNALVAR_SCALAR state into two distinct states INTERNALVAL_INTEGER and INTERNAL_POINTER; the decision can be make in set_internalvar, where we already call check_typedef, and then used subsequentially. Bye, Ulrich -- Dr. Ulrich Weigand GNU Toolchain for Linux on System z and Cell BE Ulrich.Weigand@de.ibm.com ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [RFA] Fix crash of convenience vars with typedefs. 2009-08-17 13:11 ` Ulrich Weigand @ 2009-08-17 16:10 ` Tom Tromey 2009-08-17 18:24 ` Ulrich Weigand 2009-08-17 18:22 ` Ulrich Weigand 1 sibling, 1 reply; 7+ messages in thread From: Tom Tromey @ 2009-08-17 16:10 UTC (permalink / raw) To: Ulrich Weigand; +Cc: Doug Evans, gdb-patches >>>>> "Ulrich" == Ulrich Weigand <uweigand@de.ibm.com> writes: Ulrich> Shouldn't the result of value_of_internalvar still have the original Ulrich> typedef name instead of the type it resolves to? This would be nice -- the wide character code relies on type names now, for instance -- but most of gdb already eagerly strips typedefs. E.g., look at value_cast, where the resulting value is not actually of the type you pass in, but rather the type after stripping typedefs. Tom ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [RFA] Fix crash of convenience vars with typedefs. 2009-08-17 16:10 ` Tom Tromey @ 2009-08-17 18:24 ` Ulrich Weigand 0 siblings, 0 replies; 7+ messages in thread From: Ulrich Weigand @ 2009-08-17 18:24 UTC (permalink / raw) To: tromey; +Cc: Doug Evans, gdb-patches Tom Tromey wrote: > >>>>> "Ulrich" == Ulrich Weigand <uweigand@de.ibm.com> writes: > > Ulrich> Shouldn't the result of value_of_internalvar still have the original > Ulrich> typedef name instead of the type it resolves to? > > This would be nice -- the wide character code relies on type names now, > for instance -- but most of gdb already eagerly strips typedefs. E.g., > look at value_cast, where the resulting value is not actually of the > type you pass in, but rather the type after stripping typedefs. Indeed. It seems to me that those instances ought to fixed, however, and we should avoid introducing new instances where possible ... Bye, Ulrich -- Dr. Ulrich Weigand GNU Toolchain for Linux on System z and Cell BE Ulrich.Weigand@de.ibm.com ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [RFA] Fix crash of convenience vars with typedefs. 2009-08-17 13:11 ` Ulrich Weigand 2009-08-17 16:10 ` Tom Tromey @ 2009-08-17 18:22 ` Ulrich Weigand 2009-08-18 18:44 ` Doug Evans 1 sibling, 1 reply; 7+ messages in thread From: Ulrich Weigand @ 2009-08-17 18:22 UTC (permalink / raw) To: dje; +Cc: gdb-patches I wrote: > Maybe it would be best to split the INTERNALVAR_SCALAR state into two > distinct states INTERNALVAL_INTEGER and INTERNAL_POINTER; the decision > can be make in set_internalvar, where we already call check_typedef, > and then used subsequentially. Like so. Does this fix your problem? Bye, Ulrich ChangeLog: * value.c (enum internalvar_kind): Replace INTERNALVAR_SCALAR by INTERNALVAR_INTEGER and INTERNALVAR_POINTER. (union internalvar_data): Replace "scalar" member by "integer" and "pointer". (value_of_internalvar): Handle INTERNALVAR_INTEGER and INTERNALVAR_POINTER instead of INTERNALVAR_SCALAR. (get_internalvar_integer): Likewise. (set_internalvar): Likewise. (set_internalvar_integer): Likewise. (preserve_one_internalvar): Likewise. Index: gdb/value.c =================================================================== RCS file: /cvs/src/src/gdb/value.c,v retrieving revision 1.92 diff -u -p -r1.92 value.c --- gdb/value.c 13 Aug 2009 18:39:20 -0000 1.92 +++ gdb/value.c 17 Aug 2009 17:06:30 -0000 @@ -920,8 +920,11 @@ struct internalvar /* The internal variable holds a GDB internal convenience function. */ INTERNALVAR_FUNCTION, - /* The variable holds a simple scalar value. */ - INTERNALVAR_SCALAR, + /* The variable holds an integer value. */ + INTERNALVAR_INTEGER, + + /* The variable holds a pointer value. */ + INTERNALVAR_POINTER, /* The variable holds a GDB-provided string. */ INTERNALVAR_STRING, @@ -944,19 +947,22 @@ struct internalvar int canonical; } fn; - /* A scalar value used with INTERNALVAR_SCALAR. */ + /* An integer value used with INTERNALVAR_INTEGER. */ struct { /* If type is non-NULL, it will be used as the type to generate a value for this internal variable. If type is NULL, a default integer type for the architecture is used. */ struct type *type; - union - { - LONGEST l; /* Used with TYPE_CODE_INT and NULL types. */ - CORE_ADDR a; /* Used with TYPE_CODE_PTR types. */ - } val; - } scalar; + LONGEST val; + } integer; + + /* A pointer value used with INTERNALVAR_POINTER. */ + struct + { + struct type *type; + CORE_ADDR val; + } pointer; /* A string value used with INTERNALVAR_STRING. */ char *string; @@ -1082,16 +1088,16 @@ value_of_internalvar (struct gdbarch *gd val = allocate_value (builtin_type (gdbarch)->internal_fn); break; - case INTERNALVAR_SCALAR: - if (!var->u.scalar.type) + case INTERNALVAR_INTEGER: + if (!var->u.integer.type) val = value_from_longest (builtin_type (gdbarch)->builtin_int, - var->u.scalar.val.l); - else if (TYPE_CODE (var->u.scalar.type) == TYPE_CODE_INT) - val = value_from_longest (var->u.scalar.type, var->u.scalar.val.l); - else if (TYPE_CODE (var->u.scalar.type) == TYPE_CODE_PTR) - val = value_from_pointer (var->u.scalar.type, var->u.scalar.val.a); + var->u.integer.val); else - internal_error (__FILE__, __LINE__, "bad type"); + val = value_from_longest (var->u.integer.type, var->u.integer.val); + break; + + case INTERNALVAR_POINTER: + val = value_from_pointer (var->u.pointer.type, var->u.pointer.val); break; case INTERNALVAR_STRING: @@ -1145,14 +1151,9 @@ get_internalvar_integer (struct internal { switch (var->kind) { - case INTERNALVAR_SCALAR: - if (var->u.scalar.type == NULL - || TYPE_CODE (var->u.scalar.type) == TYPE_CODE_INT) - { - *result = var->u.scalar.val.l; - return 1; - } - /* Fall through. */ + case INTERNALVAR_INTEGER: + *result = var->u.integer.val; + return 1; default: return 0; @@ -1224,15 +1225,15 @@ set_internalvar (struct internalvar *var break; case TYPE_CODE_INT: - new_kind = INTERNALVAR_SCALAR; - new_data.scalar.type = value_type (val); - new_data.scalar.val.l = value_as_long (val); + new_kind = INTERNALVAR_INTEGER; + new_data.integer.type = value_type (val); + new_data.integer.val = value_as_long (val); break; case TYPE_CODE_PTR: - new_kind = INTERNALVAR_SCALAR; - new_data.scalar.type = value_type (val); - new_data.scalar.val.a = value_as_address (val); + new_kind = INTERNALVAR_POINTER; + new_data.pointer.type = value_type (val); + new_data.pointer.val = value_as_address (val); break; default: @@ -1269,9 +1270,9 @@ set_internalvar_integer (struct internal /* Clean up old contents. */ clear_internalvar (var); - var->kind = INTERNALVAR_SCALAR; - var->u.scalar.type = NULL; - var->u.scalar.val.l = l; + var->kind = INTERNALVAR_INTEGER; + var->u.integer.type = NULL; + var->u.integer.val = l; } void @@ -1426,10 +1427,16 @@ preserve_one_internalvar (struct interna { switch (var->kind) { - case INTERNALVAR_SCALAR: - if (var->u.scalar.type && TYPE_OBJFILE (var->u.scalar.type) == objfile) - var->u.scalar.type - = copy_type_recursive (objfile, var->u.scalar.type, copied_types); + case INTERNALVAR_INTEGER: + if (var->u.integer.type && TYPE_OBJFILE (var->u.integer.type) == objfile) + var->u.integer.type + = copy_type_recursive (objfile, var->u.integer.type, copied_types); + break; + + case INTERNALVAR_POINTER: + if (TYPE_OBJFILE (var->u.pointer.type) == objfile) + var->u.pointer.type + = copy_type_recursive (objfile, var->u.pointer.type, copied_types); break; case INTERNALVAR_VALUE: -- Dr. Ulrich Weigand GNU Toolchain for Linux on System z and Cell BE Ulrich.Weigand@de.ibm.com ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [RFA] Fix crash of convenience vars with typedefs. 2009-08-17 18:22 ` Ulrich Weigand @ 2009-08-18 18:44 ` Doug Evans 2009-08-19 16:43 ` [commit] " Ulrich Weigand 0 siblings, 1 reply; 7+ messages in thread From: Doug Evans @ 2009-08-18 18:44 UTC (permalink / raw) To: Ulrich Weigand; +Cc: gdb-patches On Mon, Aug 17, 2009 at 11:16 AM, Ulrich Weigand<uweigand@de.ibm.com> wrote: > I wrote: >> Maybe it would be best to split the INTERNALVAR_SCALAR state into two >> distinct states INTERNALVAL_INTEGER and INTERNAL_POINTER; the decision >> can be make in set_internalvar, where we already call check_typedef, >> and then used subsequentially. > > Like so. Does this fix your problem? Almost. gdb now crashes in a different place. [from testsuite/gdb.log] print /x $prog_var ../../../src/gdb/findvar.c:246: internal-error: store_typed_address: type is not a pointer or reference A problem internal to GDB has been detected, further debugging may prove unreliable. Quit this debugging session? (y or n) FAIL: gdb.base/gdbvars.exp: Print contents of new convenience variable of program variable (GDB internal error) n ../../../src/gdb/findvar.c:246: internal-error: store_typed_address: type is not a pointer or reference A problem internal to GDB has been detected, further debugging may prove unreliable. Can you run the testcase included in my patch? If that passes I'm happy. > > Bye, > Ulrich > > > ChangeLog: > > * value.c (enum internalvar_kind): Replace INTERNALVAR_SCALAR by > INTERNALVAR_INTEGER and INTERNALVAR_POINTER. > (union internalvar_data): Replace "scalar" member by "integer" > and "pointer". > (value_of_internalvar): Handle INTERNALVAR_INTEGER and > INTERNALVAR_POINTER instead of INTERNALVAR_SCALAR. > (get_internalvar_integer): Likewise. > (set_internalvar): Likewise. > (set_internalvar_integer): Likewise. > (preserve_one_internalvar): Likewise. > > > Index: gdb/value.c > =================================================================== > RCS file: /cvs/src/src/gdb/value.c,v > retrieving revision 1.92 > diff -u -p -r1.92 value.c > --- gdb/value.c 13 Aug 2009 18:39:20 -0000 1.92 > +++ gdb/value.c 17 Aug 2009 17:06:30 -0000 > @@ -920,8 +920,11 @@ struct internalvar > /* The internal variable holds a GDB internal convenience function. */ > INTERNALVAR_FUNCTION, > > - /* The variable holds a simple scalar value. */ > - INTERNALVAR_SCALAR, > + /* The variable holds an integer value. */ > + INTERNALVAR_INTEGER, > + > + /* The variable holds a pointer value. */ > + INTERNALVAR_POINTER, > > /* The variable holds a GDB-provided string. */ > INTERNALVAR_STRING, > @@ -944,19 +947,22 @@ struct internalvar > int canonical; > } fn; > > - /* A scalar value used with INTERNALVAR_SCALAR. */ > + /* An integer value used with INTERNALVAR_INTEGER. */ > struct > { > /* If type is non-NULL, it will be used as the type to generate > a value for this internal variable. If type is NULL, a default > integer type for the architecture is used. */ > struct type *type; > - union > - { > - LONGEST l; /* Used with TYPE_CODE_INT and NULL types. */ > - CORE_ADDR a; /* Used with TYPE_CODE_PTR types. */ > - } val; > - } scalar; > + LONGEST val; > + } integer; > + > + /* A pointer value used with INTERNALVAR_POINTER. */ > + struct > + { > + struct type *type; > + CORE_ADDR val; > + } pointer; > > /* A string value used with INTERNALVAR_STRING. */ > char *string; > @@ -1082,16 +1088,16 @@ value_of_internalvar (struct gdbarch *gd > val = allocate_value (builtin_type (gdbarch)->internal_fn); > break; > > - case INTERNALVAR_SCALAR: > - if (!var->u.scalar.type) > + case INTERNALVAR_INTEGER: > + if (!var->u.integer.type) > val = value_from_longest (builtin_type (gdbarch)->builtin_int, > - var->u.scalar.val.l); > - else if (TYPE_CODE (var->u.scalar.type) == TYPE_CODE_INT) > - val = value_from_longest (var->u.scalar.type, var->u.scalar.val.l); > - else if (TYPE_CODE (var->u.scalar.type) == TYPE_CODE_PTR) > - val = value_from_pointer (var->u.scalar.type, var->u.scalar.val.a); > + var->u.integer.val); > else > - internal_error (__FILE__, __LINE__, "bad type"); > + val = value_from_longest (var->u.integer.type, var->u.integer.val); > + break; > + > + case INTERNALVAR_POINTER: > + val = value_from_pointer (var->u.pointer.type, var->u.pointer.val); > break; > > case INTERNALVAR_STRING: > @@ -1145,14 +1151,9 @@ get_internalvar_integer (struct internal > { > switch (var->kind) > { > - case INTERNALVAR_SCALAR: > - if (var->u.scalar.type == NULL > - || TYPE_CODE (var->u.scalar.type) == TYPE_CODE_INT) > - { > - *result = var->u.scalar.val.l; > - return 1; > - } > - /* Fall through. */ > + case INTERNALVAR_INTEGER: > + *result = var->u.integer.val; > + return 1; > > default: > return 0; > @@ -1224,15 +1225,15 @@ set_internalvar (struct internalvar *var > break; > > case TYPE_CODE_INT: > - new_kind = INTERNALVAR_SCALAR; > - new_data.scalar.type = value_type (val); > - new_data.scalar.val.l = value_as_long (val); > + new_kind = INTERNALVAR_INTEGER; > + new_data.integer.type = value_type (val); > + new_data.integer.val = value_as_long (val); > break; > > case TYPE_CODE_PTR: > - new_kind = INTERNALVAR_SCALAR; > - new_data.scalar.type = value_type (val); > - new_data.scalar.val.a = value_as_address (val); > + new_kind = INTERNALVAR_POINTER; > + new_data.pointer.type = value_type (val); > + new_data.pointer.val = value_as_address (val); > break; > > default: > @@ -1269,9 +1270,9 @@ set_internalvar_integer (struct internal > /* Clean up old contents. */ > clear_internalvar (var); > > - var->kind = INTERNALVAR_SCALAR; > - var->u.scalar.type = NULL; > - var->u.scalar.val.l = l; > + var->kind = INTERNALVAR_INTEGER; > + var->u.integer.type = NULL; > + var->u.integer.val = l; > } > > void > @@ -1426,10 +1427,16 @@ preserve_one_internalvar (struct interna > { > switch (var->kind) > { > - case INTERNALVAR_SCALAR: > - if (var->u.scalar.type && TYPE_OBJFILE (var->u.scalar.type) == objfile) > - var->u.scalar.type > - = copy_type_recursive (objfile, var->u.scalar.type, copied_types); > + case INTERNALVAR_INTEGER: > + if (var->u.integer.type && TYPE_OBJFILE (var->u.integer.type) == objfile) > + var->u.integer.type > + = copy_type_recursive (objfile, var->u.integer.type, copied_types); > + break; > + > + case INTERNALVAR_POINTER: > + if (TYPE_OBJFILE (var->u.pointer.type) == objfile) > + var->u.pointer.type > + = copy_type_recursive (objfile, var->u.pointer.type, copied_types); > break; > > case INTERNALVAR_VALUE: > > -- > Dr. Ulrich Weigand > GNU Toolchain for Linux on System z and Cell BE > Ulrich.Weigand@de.ibm.com > ^ permalink raw reply [flat|nested] 7+ messages in thread
* [commit] Re: [RFA] Fix crash of convenience vars with typedefs. 2009-08-18 18:44 ` Doug Evans @ 2009-08-19 16:43 ` Ulrich Weigand 0 siblings, 0 replies; 7+ messages in thread From: Ulrich Weigand @ 2009-08-19 16:43 UTC (permalink / raw) To: Doug Evans; +Cc: gdb-patches Doug Evans wrote: > Almost. gdb now crashes in a different place. Huh. I guess value_from_pointer needs to handle typedef'd types, just like all the other value_from_... routines do. > Can you run the testcase included in my patch? > If that passes I'm happy. With the value_from_pointer change your test case does run without problems. I've now committed the patch below, including the test. Tested on powerpc64-linux. Bye, Ulrich ChangeLog: * value.c (enum internalvar_kind): Replace INTERNALVAR_SCALAR by INTERNALVAR_INTEGER and INTERNALVAR_POINTER. (union internalvar_data): Replace "scalar" member by "integer" and "pointer". (value_of_internalvar): Handle INTERNALVAR_INTEGER and INTERNALVAR_POINTER instead of INTERNALVAR_SCALAR. (get_internalvar_integer): Likewise. (set_internalvar): Likewise. (set_internalvar_integer): Likewise. (preserve_one_internalvar): Likewise. (value_from_pointer): Handle typedef'd pointer types. testsuite/ChangeLog: 2009-08-19 Doug Evans <dje@google.com> * gdb.base/gdbvars.c: New file. * gdb.base/gdbvars.exp: Test convenience vars with program variables. Index: gdb/value.c =================================================================== RCS file: /cvs/src/src/gdb/value.c,v retrieving revision 1.92 diff -u -p -r1.92 value.c --- gdb/value.c 13 Aug 2009 18:39:20 -0000 1.92 +++ gdb/value.c 19 Aug 2009 11:12:00 -0000 @@ -920,8 +920,11 @@ struct internalvar /* The internal variable holds a GDB internal convenience function. */ INTERNALVAR_FUNCTION, - /* The variable holds a simple scalar value. */ - INTERNALVAR_SCALAR, + /* The variable holds an integer value. */ + INTERNALVAR_INTEGER, + + /* The variable holds a pointer value. */ + INTERNALVAR_POINTER, /* The variable holds a GDB-provided string. */ INTERNALVAR_STRING, @@ -944,19 +947,22 @@ struct internalvar int canonical; } fn; - /* A scalar value used with INTERNALVAR_SCALAR. */ + /* An integer value used with INTERNALVAR_INTEGER. */ struct { /* If type is non-NULL, it will be used as the type to generate a value for this internal variable. If type is NULL, a default integer type for the architecture is used. */ struct type *type; - union - { - LONGEST l; /* Used with TYPE_CODE_INT and NULL types. */ - CORE_ADDR a; /* Used with TYPE_CODE_PTR types. */ - } val; - } scalar; + LONGEST val; + } integer; + + /* A pointer value used with INTERNALVAR_POINTER. */ + struct + { + struct type *type; + CORE_ADDR val; + } pointer; /* A string value used with INTERNALVAR_STRING. */ char *string; @@ -1082,16 +1088,16 @@ value_of_internalvar (struct gdbarch *gd val = allocate_value (builtin_type (gdbarch)->internal_fn); break; - case INTERNALVAR_SCALAR: - if (!var->u.scalar.type) + case INTERNALVAR_INTEGER: + if (!var->u.integer.type) val = value_from_longest (builtin_type (gdbarch)->builtin_int, - var->u.scalar.val.l); - else if (TYPE_CODE (var->u.scalar.type) == TYPE_CODE_INT) - val = value_from_longest (var->u.scalar.type, var->u.scalar.val.l); - else if (TYPE_CODE (var->u.scalar.type) == TYPE_CODE_PTR) - val = value_from_pointer (var->u.scalar.type, var->u.scalar.val.a); + var->u.integer.val); else - internal_error (__FILE__, __LINE__, "bad type"); + val = value_from_longest (var->u.integer.type, var->u.integer.val); + break; + + case INTERNALVAR_POINTER: + val = value_from_pointer (var->u.pointer.type, var->u.pointer.val); break; case INTERNALVAR_STRING: @@ -1145,14 +1151,9 @@ get_internalvar_integer (struct internal { switch (var->kind) { - case INTERNALVAR_SCALAR: - if (var->u.scalar.type == NULL - || TYPE_CODE (var->u.scalar.type) == TYPE_CODE_INT) - { - *result = var->u.scalar.val.l; - return 1; - } - /* Fall through. */ + case INTERNALVAR_INTEGER: + *result = var->u.integer.val; + return 1; default: return 0; @@ -1224,15 +1225,15 @@ set_internalvar (struct internalvar *var break; case TYPE_CODE_INT: - new_kind = INTERNALVAR_SCALAR; - new_data.scalar.type = value_type (val); - new_data.scalar.val.l = value_as_long (val); + new_kind = INTERNALVAR_INTEGER; + new_data.integer.type = value_type (val); + new_data.integer.val = value_as_long (val); break; case TYPE_CODE_PTR: - new_kind = INTERNALVAR_SCALAR; - new_data.scalar.type = value_type (val); - new_data.scalar.val.a = value_as_address (val); + new_kind = INTERNALVAR_POINTER; + new_data.pointer.type = value_type (val); + new_data.pointer.val = value_as_address (val); break; default: @@ -1269,9 +1270,9 @@ set_internalvar_integer (struct internal /* Clean up old contents. */ clear_internalvar (var); - var->kind = INTERNALVAR_SCALAR; - var->u.scalar.type = NULL; - var->u.scalar.val.l = l; + var->kind = INTERNALVAR_INTEGER; + var->u.integer.type = NULL; + var->u.integer.val = l; } void @@ -1426,10 +1427,16 @@ preserve_one_internalvar (struct interna { switch (var->kind) { - case INTERNALVAR_SCALAR: - if (var->u.scalar.type && TYPE_OBJFILE (var->u.scalar.type) == objfile) - var->u.scalar.type - = copy_type_recursive (objfile, var->u.scalar.type, copied_types); + case INTERNALVAR_INTEGER: + if (var->u.integer.type && TYPE_OBJFILE (var->u.integer.type) == objfile) + var->u.integer.type + = copy_type_recursive (objfile, var->u.integer.type, copied_types); + break; + + case INTERNALVAR_POINTER: + if (TYPE_OBJFILE (var->u.pointer.type) == objfile) + var->u.pointer.type + = copy_type_recursive (objfile, var->u.pointer.type, copied_types); break; case INTERNALVAR_VALUE: @@ -2164,7 +2171,7 @@ struct value * value_from_pointer (struct type *type, CORE_ADDR addr) { struct value *val = allocate_value (type); - store_typed_address (value_contents_raw (val), type, addr); + store_typed_address (value_contents_raw (val), check_typedef (type), addr); return val; } Index: gdb/testsuite/gdb.base/gdbvars.c =================================================================== RCS file: gdb/testsuite/gdb.base/gdbvars.c diff -N gdb/testsuite/gdb.base/gdbvars.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ gdb/testsuite/gdb.base/gdbvars.c 14 Aug 2009 23:58:45 -0000 @@ -0,0 +1,16 @@ +/* Simple program to help exercise gdb's convenience variables. */ + +typedef void *ptr; + +ptr p = &p; + +int +main () +{ +#ifdef usestubs + set_debug_traps (); + breakpoint (); +#endif + + return 0; +} Index: gdb/testsuite/gdb.base/gdbvars.exp =================================================================== RCS file: /cvs/src/src/gdb/testsuite/gdb.base/gdbvars.exp,v retrieving revision 1.6 diff -u -p -r1.6 gdbvars.exp --- gdb/testsuite/gdb.base/gdbvars.exp 3 Jan 2009 05:58:03 -0000 1.6 +++ gdb/testsuite/gdb.base/gdbvars.exp 14 Aug 2009 23:58:45 -0000 @@ -22,6 +22,15 @@ if $tracelevel then { set prms_id 0 set bug_id 0 +set testfile "gdbvars" +set srcfile ${testfile}.c +set binfile ${objdir}/${subdir}/${testfile} + +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { + untested gdbvars.exp + return -1 +} + proc test_convenience_variables {} { global gdb_prompt @@ -101,13 +110,23 @@ proc test_value_history {} { "Use value-history element in arithmetic expression" } +proc test_with_program {} { + global hex + gdb_test "set \$prog_var = p" "" \ + "Set a new convenience variable to a program variable" + gdb_test "print /x \$prog_var" " = $hex" \ + "Print contents of new convenience variable of program variable" +} + # Start with a fresh gdb. gdb_exit gdb_start gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} send_gdb "set print sevenbit-strings\n" ; gdb_expect -re ".*$gdb_prompt $" test_value_history test_convenience_variables +test_with_program -- Dr. Ulrich Weigand GNU Toolchain for Linux on System z and Cell BE Ulrich.Weigand@de.ibm.com ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2009-08-19 13:03 UTC | newest] Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2009-08-15 0:22 [RFA] Fix crash of convenience vars with typedefs Doug Evans 2009-08-17 13:11 ` Ulrich Weigand 2009-08-17 16:10 ` Tom Tromey 2009-08-17 18:24 ` Ulrich Weigand 2009-08-17 18:22 ` Ulrich Weigand 2009-08-18 18:44 ` Doug Evans 2009-08-19 16:43 ` [commit] " Ulrich Weigand
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox