This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFA] Fix crash of convenience vars with typedefs.


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]