This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[commit] Re: [RFA] Fix crash of convenience vars with typedefs.
- From: "Ulrich Weigand" <uweigand at de dot ibm dot com>
- To: dje at google dot com (Doug Evans)
- Cc: gdb-patches at sourceware dot org
- Date: Wed, 19 Aug 2009 15:03:25 +0200 (CEST)
- Subject: [commit] Re: [RFA] Fix crash of convenience vars with typedefs.
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