http://sourceware.org/ml/gdb-patches/2009-08/msg00310.html http://sourceware.org/ml/gdb-cvs/2009-08/msg00092.html 2009-08-19 Ulrich Weigand * 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. 2009-08-19 Doug Evans * gdb.base/gdbvars.c: New file. * gdb.base/gdbvars.exp: Test convenience vars with program variables. --- src/gdb/value.c 2009/08/13 18:39:20 1.92 +++ src/gdb/value.c 2009/08/19 13:00:28 1.93 @@ -920,8 +920,11 @@ /* 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 @@ 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 @@ 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 @@ { 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 @@ 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 @@ /* 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 @@ { 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 @@ 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; } --- src/gdb/testsuite/gdb.base/gdbvars.c +++ src/gdb/testsuite/gdb.base/gdbvars.c 2009-08-19 15:10:47.270783000 +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; +} --- src/gdb/testsuite/gdb.base/gdbvars.exp 2009/01/03 05:58:03 1.6 +++ src/gdb/testsuite/gdb.base/gdbvars.exp 2009/08/19 13:00:29 1.7 @@ -22,6 +22,15 @@ 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 @@ "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