From fcacd99f87bf1f39ba0b3fde4a71b2876c20bd70 Mon Sep 17 00:00:00 2001 From: Vladimir Prus Date: Sun, 13 Apr 2008 09:33:49 +0000 Subject: [PATCH] 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. --- gdb/ChangeLog | 9 ++++++ gdb/mi/mi-cmd-var.c | 1 + gdb/testsuite/ChangeLog | 11 +++++++ gdb/testsuite/gdb.mi/mi-var-cmd.exp | 17 +++++++++-- gdb/testsuite/gdb.mi/mi2-var-cmd.exp | 4 +-- gdb/testsuite/gdb.mi/var-cmd.c | 57 ++++++++++++++++++++++++++++++++++++ gdb/testsuite/lib/mi-support.exp | 14 +++++++++ gdb/varobj.c | 10 +++++++ 8 files changed, 119 insertions(+), 4 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 8565ee0..c0ec976 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,12 @@ +2008-04-13 Nick Roberts + Vladimir Prus + + 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 * mi/mi-cmd-var.c: Include "mi-getopt.h". diff --git a/gdb/mi/mi-cmd-var.c b/gdb/mi/mi-cmd-var.c index ddea2cf..9c0df69 100644 --- a/gdb/mi/mi-cmd-var.c +++ b/gdb/mi/mi-cmd-var.c @@ -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)); diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 245bc58..61a75f0 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,14 @@ +2008-04-13 Vladimir Prus + + * 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 * gdb.mi/mi2-var-display.exp: Added tests for the new -f diff --git a/gdb/testsuite/gdb.mi/mi-var-cmd.exp b/gdb/testsuite/gdb.mi/mi-var-cmd.exp index 8e7db1f..c1ae813 100644 --- a/gdb/testsuite/gdb.mi/mi-var-cmd.exp +++ b/gdb/testsuite/gdb.mi/mi-var-cmd.exp @@ -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 diff --git a/gdb/testsuite/gdb.mi/mi2-var-cmd.exp b/gdb/testsuite/gdb.mi/mi2-var-cmd.exp index f815041..d980917 100644 --- a/gdb/testsuite/gdb.mi/mi2-var-cmd.exp +++ b/gdb/testsuite/gdb.mi/mi2-var-cmd.exp @@ -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 diff --git a/gdb/testsuite/gdb.mi/var-cmd.c b/gdb/testsuite/gdb.mi/var-cmd.c index 4216461..ffc442f 100644 --- a/gdb/testsuite/gdb.mi/var-cmd.c +++ b/gdb/testsuite/gdb.mi/var-cmd.c @@ -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); } diff --git a/gdb/testsuite/lib/mi-support.exp b/gdb/testsuite/lib/mi-support.exp index 317ba49..6528fb4 100644 --- a/gdb/testsuite/lib/mi-support.exp +++ b/gdb/testsuite/lib/mi-support.exp @@ -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" \ diff --git a/gdb/varobj.c b/gdb/varobj.c index 7f7fda2..b27013c 100644 --- a/gdb/varobj.c +++ b/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; } -- 2.7.4