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.
This commit is contained in:
parent
350fc95b2b
commit
fcacd99f87
8 changed files with 119 additions and 4 deletions
|
@ -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".
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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" \
|
||||
|
|
10
gdb/varobj.c
10
gdb/varobj.c
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue