Fix @-varobjs.
authorVladimir Prus <vladimir@codesourcery.com>
Sun, 13 Apr 2008 09:33:49 +0000 (09:33 +0000)
committerVladimir Prus <vladimir@codesourcery.com>
Sun, 13 Apr 2008 09:33:49 +0000 (09:33 +0000)
        * 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.

gdb/ChangeLog
gdb/mi/mi-cmd-var.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.mi/mi-var-cmd.exp
gdb/testsuite/gdb.mi/mi2-var-cmd.exp
gdb/testsuite/gdb.mi/var-cmd.c
gdb/testsuite/lib/mi-support.exp
gdb/varobj.c

index 8565ee0..c0ec976 100644 (file)
@@ -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 ddea2cf..9c0df69 100644 (file)
@@ -683,6 +683,7 @@ varobj_update_one (struct varobj *var, enum print_values print_values,
          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 245bc58..61a75f0 100644 (file)
@@ -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 8e7db1f..c1ae813 100644 (file)
@@ -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 f815041..d980917 100644 (file)
@@ -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 4216461..ffc442f 100644 (file)
@@ -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 317ba49..6528fb4 100644 (file)
@@ -1064,6 +1064,13 @@ proc mi_create_varobj { name expression testname } {
         $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 testname } {
     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 7f7fda2..b27013c 100644 (file)
@@ -1751,6 +1751,16 @@ value_of_root (struct varobj **var_handle, int *type_changed)
       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;
        }