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]

Fix floating varobjs


I've checked in the below patch to fix floating varobj. The bug was
discovered by Nick, and the code patch was provided by Nick as well.
I've analysed why exactly the bug happens (see comments in the code),
and fixed the output of the 'type_changed' field for floating varobjs,
and also wrote the tests.

- Volodya

Index: gdb/ChangeLog
===================================================================
RCS file: /cvs/src/src/gdb/ChangeLog,v
retrieving revision 1.9276
diff -u -p -r1.9276 ChangeLog
--- gdb/ChangeLog	9 Apr 2008 13:29:52 -0000	1.9276
+++ gdb/ChangeLog	13 Apr 2008 09:32:04 -0000
@@ -1,3 +1,12 @@
+2008-04-13  Nick Roberts  <nickrob@snap.net.nz>
+	    Vladimir Prus  <vladimir@codesourcery.com>
+
+	Fix @-varobjs.
+        * varobj.c (value_of_root): Update the expression for
+        floating varobjs.
+        * mi/mi-cmd-var.c (varobj_update_one): If type has changed,
+        report that.
+
 2008-04-09  Marc Khouzam  <marc.khouzam@ericsson.com>
 
 	* mi/mi-cmd-var.c: Include "mi-getopt.h".
Index: gdb/varobj.c
===================================================================
RCS file: /cvs/src/src/gdb/varobj.c,v
retrieving revision 1.109
diff -u -p -r1.109 varobj.c
--- gdb/varobj.c	9 Apr 2008 13:29:51 -0000	1.109
+++ gdb/varobj.c	13 Apr 2008 09:32:05 -0000
@@ -1751,6 +1751,16 @@ value_of_root (struct varobj **var_handl
       new_type = varobj_get_type (tmp_var);
       if (strcmp (old_type, new_type) == 0)
 	{
+	  /* The expression presently stored inside var->root->exp
+	     remembers the locations of local variables relatively to
+	     the frame where the expression was created (in DWARF location
+	     button, for example).  Naturally, those locations are not
+	     correct in other frames, so update the expression.  */
+
+         struct expression *tmp_exp = var->root->exp;
+         var->root->exp = tmp_var->root->exp;
+         tmp_var->root->exp = tmp_exp;
+
 	  varobj_delete (tmp_var, NULL, 0);
 	  *type_changed = 0;
 	}
Index: gdb/mi/mi-cmd-var.c
===================================================================
RCS file: /cvs/src/src/gdb/mi/mi-cmd-var.c,v
retrieving revision 1.48
diff -u -p -r1.48 mi-cmd-var.c
--- gdb/mi/mi-cmd-var.c	9 Apr 2008 13:29:55 -0000	1.48
+++ gdb/mi/mi-cmd-var.c	13 Apr 2008 09:32:06 -0000
@@ -683,6 +683,7 @@ varobj_update_one (struct varobj *var, e
  	  break;
         case TYPE_CHANGED:
 	  ui_out_field_string (uiout, "in_scope", "true");
+	  ui_out_field_string (uiout, "type_changed", "true");
           ui_out_field_string (uiout, "new_type", varobj_get_type(var));
           ui_out_field_int (uiout, "new_num_children", 
 			    varobj_get_num_children(var));
Index: gdb/testsuite/ChangeLog
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/ChangeLog,v
retrieving revision 1.1604
diff -u -p -r1.1604 ChangeLog
--- gdb/testsuite/ChangeLog	9 Apr 2008 13:29:54 -0000	1.1604
+++ gdb/testsuite/ChangeLog	13 Apr 2008 09:32:12 -0000
@@ -1,3 +1,14 @@
+2008-04-13  Vladimir Prus  <vladimir@codesourcery.com>
+
+	* gdb.mi/mi-var-cmd.exp: Adjust for appearance of type_changed
+        field.  Add more floating varobj tests.
+	* gdb.mi/mi2-var-cmd.exp: Adjust for appearance of type_changed
+        field.
+        * gdb.mi/var-cmd.c (do_at_tests_callee, do_at_tests): New.
+        (main): Call do_at_tests.
+        * lib/mi-support.exp (mi_create_floating_varobj)
+        (mi_varobj_update_with_type_change): New.
+
 2008-04-09  Marc Khouzam  <marc.khouzam@ericsson.com>
 
 	* gdb.mi/mi2-var-display.exp: Added tests for the new -f
Index: gdb/testsuite/gdb.mi/mi-var-cmd.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.mi/mi-var-cmd.exp,v
retrieving revision 1.37
diff -u -p -r1.37 mi-var-cmd.exp
--- gdb/testsuite/gdb.mi/mi-var-cmd.exp	4 Apr 2008 21:59:25 -0000	1.37
+++ gdb/testsuite/gdb.mi/mi-var-cmd.exp	13 Apr 2008 09:32:12 -0000
@@ -550,14 +550,14 @@ mi_gdb_test "-var-create selected_a @ a"
 mi_continue_to incr_a
 
 mi_gdb_test "-var-update selected_a" \
-	"\\^done,changelist=\\\[\{name=\"selected_a\",in_scope=\"true\",new_type=\"char\",new_num_children=\"0\"\}\\\]" \
+	"\\^done,changelist=\\\[\{name=\"selected_a\",in_scope=\"true\",type_changed=\"true\",new_type=\"char\",new_num_children=\"0\"\}\\\]" \
 	"update selected_a in incr_a"
 
 mi_next "step a line in incr_a"
 mi_next "return from incr_a to do_special_tests"
 
 mi_gdb_test "-var-update selected_a" \
-	"\\^done,changelist=\\\[\{name=\"selected_a\",in_scope=\"true\",new_type=\"int\",new_num_children=\"0\"\}\\\]" \
+	"\\^done,changelist=\\\[\{name=\"selected_a\",in_scope=\"true\",type_changed=\"true\",new_type=\"int\",new_num_children=\"0\"\}\\\]" \
 	"update selected_a in do_special_tests"
 
 mi_delete_varobj selected_a "delete selected_a"
@@ -574,6 +574,19 @@ proc set_frozen {varobjs flag} {
 mi_prepare_inline_tests $srcfile
 mi_run_inline_test frozen
 
+# Since the inline test framework does not really work with
+# function calls, first to inline tests and then do the reminder
+# manually.
+mi_run_inline_test floating
+set do_at_tests_callee_breakpoint [gdb_get_line_number "breakpoint inside callee"]
+mi_gdb_test "-break-insert var-cmd.c:$do_at_tests_callee_breakpoint" ".*" \
+    "inside breakpoint inside callee"
+mi_execute_to "exec-continue" "breakpoint-hit" do_at_tests_callee "" ".*" ".*" ""\
+    "continue to where i is initialized"
+
+mi_varobj_update F {F} "update F inside callee"
+mi_check_varobj_value F 7 "check F inside callee"
+
 # Test whether bad varobjs crash GDB.
 
 # A varobj we fail to read during -var-update should be considered
Index: gdb/testsuite/gdb.mi/mi2-var-cmd.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.mi/mi2-var-cmd.exp,v
retrieving revision 1.18
diff -u -p -r1.18 mi2-var-cmd.exp
--- gdb/testsuite/gdb.mi/mi2-var-cmd.exp	4 Apr 2008 21:59:25 -0000	1.18
+++ gdb/testsuite/gdb.mi/mi2-var-cmd.exp	13 Apr 2008 09:32:12 -0000
@@ -513,14 +513,14 @@ mi_gdb_test "-var-create selected_a @ a"
 mi_continue_to incr_a
 
 mi_gdb_test "-var-update selected_a" \
-	"\\^done,changelist=\\\[\{name=\"selected_a\",in_scope=\"true\",new_type=\"char\",new_num_children=\"0\"\}\\\]" \
+	"\\^done,changelist=\\\[\{name=\"selected_a\",in_scope=\"true\",type_changed=\"true\",new_type=\"char\",new_num_children=\"0\"\}\\\]" \
 	"update selected_a in incr_a"
 
 mi_next "step a line in incr_a"
 mi_next "return from incr_a to do_special_tests"
 
 mi_gdb_test "-var-update selected_a" \
-	"\\^done,changelist=\\\[\{name=\"selected_a\",in_scope=\"true\",new_type=\"int\",new_num_children=\"0\"\}\\\]" \
+	"\\^done,changelist=\\\[\{name=\"selected_a\",in_scope=\"true\",type_changed=\"true\",new_type=\"int\",new_num_children=\"0\"\}\\\]" \
 	"update selected_a in do_special_tests"
 
 mi_gdb_exit
Index: gdb/testsuite/gdb.mi/var-cmd.c
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.mi/var-cmd.c,v
retrieving revision 1.16
diff -u -p -r1.16 var-cmd.c
--- gdb/testsuite/gdb.mi/var-cmd.c	17 Jan 2008 14:34:22 -0000	1.16
+++ gdb/testsuite/gdb.mi/var-cmd.c	13 Apr 2008 09:32:12 -0000
@@ -405,6 +405,62 @@ void do_frozen_tests ()
   /*: END: frozen :*/
 }
 
+void do_at_tests_callee ()
+{
+  /* This is a test of wrong DWARF data being assigned to expression.
+     The DWARF location expression is bound to symbol when expression
+     is parsed.  So, if we create floating varobj in one function,
+     and then try to reevaluate it in other frame without reparsing
+     the expression, we will access local variables using DWARF
+     location expression from the original frame, and are likely
+     to grab wrong symbol.  To reliably reproduce this bug, we need 
+     to wrap our variable with a bunch of buffers, so that those
+     buffers are accessed instead of the real one.  */
+  int buffer1 = 10;
+  int buffer2 = 11;
+  int buffer3 = 12;
+  int i = 7;
+  int buffer4 = 13;
+  int buffer5 = 14;
+  int buffer6 = 15;
+  i++;  /* breakpoint inside callee */
+  i++;
+}
+
+void do_at_tests ()
+{
+  int x;
+  /*: BEGIN: floating :*/
+  int i = 10;
+  int y = 15;
+  /*:
+    mi_create_floating_varobj F i "create floating varobj"
+    :*/
+  i++;
+  /*:
+    mi_varobj_update F {F} "update F (1)"
+    mi_check_varobj_value F 11 "check F (1)"
+    :*/
+  i++;
+  {
+    double i = 15;
+    /*:
+      mi_varobj_update_with_type_change F "double" "0" "update F (2)"
+      mi_check_varobj_value F 15 "check F (2)"
+      :*/
+    i += 2.0;
+  }
+  i++;
+  /*:
+    mi_varobj_update_with_type_change F "int" "0" "update F (3)"
+    mi_check_varobj_value F 13 "check F (3)"
+    :*/
+  i++;
+  do_at_tests_callee ();
+  i++;
+  /*: END: floating :*/
+}
+
 int
 main (int argc, char *argv [])
 {
@@ -413,6 +469,7 @@ main (int argc, char *argv [])
   do_children_tests ();
   do_special_tests ();
   do_frozen_tests ();
+  do_at_tests ();
   exit (0);
 }
 
Index: gdb/testsuite/lib/mi-support.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/lib/mi-support.exp,v
retrieving revision 1.54
diff -u -p -r1.54 mi-support.exp
--- gdb/testsuite/lib/mi-support.exp	5 Apr 2008 17:12:46 -0000	1.54
+++ gdb/testsuite/lib/mi-support.exp	13 Apr 2008 09:32:12 -0000
@@ -1064,6 +1064,13 @@ proc mi_create_varobj { name expression 
         $testname
 }
 
+proc mi_create_floating_varobj { name expression testname } {
+    mi_gdb_test "-var-create $name @ $expression" \
+        "\\^done,name=\"$name\",numchild=\"\[0-9\]+\",value=\".*\",type=.*" \
+        $testname
+}
+
+
 # Same as mi_create_varobj, but also checks the reported type
 # of the varobj.
 proc mi_create_varobj_checked { name expression type testname } {
@@ -1101,6 +1108,13 @@ proc mi_varobj_update { name expected te
     mi_gdb_test "-var-update $name" $er $testname
 }
 
+proc mi_varobj_update_with_type_change { name new_type new_children testname } {
+    set v "{name=\"$name\",in_scope=\"true\",type_changed=\"true\",new_type=\"$new_type\",new_num_children=\"$new_children\"}"
+    set er "\\^done,changelist=\\\[$v\\\]"
+    verbose -log "Expecting: $er"
+    mi_gdb_test "-var-update $name" $er $testname
+}
+
 proc mi_check_varobj_value { name value testname } {
 
     mi_gdb_test "-var-evaluate-expression $name" \

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