+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".
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));
+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
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"
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
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
/*: 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 [])
{
do_children_tests ();
do_special_tests ();
do_frozen_tests ();
+ do_at_tests ();
exit (0);
}
$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 } {
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" \
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;
}