diff options
-rw-r--r-- | gdb/ChangeLog | 24 | ||||
-rw-r--r-- | gdb/mi/ChangeLog-mi | 7 | ||||
-rw-r--r-- | gdb/mi/mi-cmd-var.c | 65 | ||||
-rw-r--r-- | gdb/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gdb/testsuite/gdb.mi/ChangeLog-mi | 8 | ||||
-rw-r--r-- | gdb/testsuite/gdb.mi/mi-var-block.exp | 4 | ||||
-rw-r--r-- | gdb/testsuite/gdb.mi/mi-var-child.exp | 33 | ||||
-rw-r--r-- | gdb/testsuite/gdb.mi/mi-var-cmd.exp | 34 | ||||
-rw-r--r-- | gdb/testsuite/lib/gdb.exp | 22 | ||||
-rw-r--r-- | gdb/varobj.c | 195 | ||||
-rw-r--r-- | gdb/varobj.h | 10 | ||||
-rw-r--r-- | gdb/wrapper.c | 41 | ||||
-rw-r--r-- | gdb/wrapper.h | 4 |
13 files changed, 351 insertions, 101 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index d00e174..7097e66 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,27 @@ +2000-03-13 James Ingham <jingham@leda.cygnus.com> + + Add support for a variable object that tries to evaluate itself in + the currently selected frame, rather than in a fixed frame. + + * wrapper.c,h (gdb_parse_exp_1): Added a wrapper for + gdb_parse_exp_1. + * varobj.h: Added USE_CURRENT_FRAME to varobj_type & changed def'n + of varobj_create. + * varobj.c (varobj_list): Return type indicates whether the + variable's type has changed (for current frame variables). + (varobj_update): Handle the case where the variable's type has + changed. + (delete_variable_1): Allow for deletion of variables that have not + been installed yet. + (new_root_variable): Initialize use_selected_frame variable. + (value_of_root): This is where most of the work to handle "current + frame" variables was added. Most of the complexity involves + handling the case where the type of the variable has changed. + (varobj_create): Add a "type" argument, to tell if the + variable is one of these "current frame" variables. Also protect + call to parse_exp_1 from long jumping. + + 2000-03-13 Eli Zaretskii <eliz@is.elta.co.il> * go32-nat.c (struct env387): Remove declaration. diff --git a/gdb/mi/ChangeLog-mi b/gdb/mi/ChangeLog-mi index 6abbfa2..eae7d38 100644 --- a/gdb/mi/ChangeLog-mi +++ b/gdb/mi/ChangeLog-mi @@ -1,3 +1,10 @@ +2000-03-13 James Ingham <jingham@leda.cygnus.com> + + * mi-cmd-var.c (mi_cmd_var_create): Add special frame cookie "@" + to indicate an "USE_CURRENT_FRAME" variable. + (varobj_update_one): Add "in_scope" and "type_changed" to the + result. + 2000-03-06 Elena Zannoni <ezannoni@kwikemart.cygnus.com> * mi-cmds.h: Export mi_cmd_data_write_register_values. diff --git a/gdb/mi/mi-cmd-var.c b/gdb/mi/mi-cmd-var.c index 568cb7e..a20f4f1 100644 --- a/gdb/mi/mi-cmd-var.c +++ b/gdb/mi/mi-cmd-var.c @@ -34,20 +34,21 @@ extern int varobjdebug; /* defined in varobj.c */ -static void varobj_update_one (struct varobj *var); +static int varobj_update_one (struct varobj *var); /* VAROBJ operations */ enum mi_cmd_result mi_cmd_var_create (char *command, char **argv, int argc) { - CORE_ADDR frameaddr; + CORE_ADDR frameaddr = 0; struct varobj *var; char *name; char *frame; char *expr; char *type; struct cleanup *old_cleanups; + enum varobj_type var_type; if (argc != 3) { @@ -77,16 +78,21 @@ mi_cmd_var_create (char *command, char **argv, int argc) error ("mi_cmd_var_create: name of object must begin with a letter"); if (strcmp (frame, "*") == 0) - frameaddr = -1; + var_type = USE_CURRENT_FRAME; + else if (strcmp (frame, "@") == 0) + var_type = USE_SELECTED_FRAME; else - frameaddr = parse_and_eval_address (frame); + { + var_type = USE_SPECIFIED_FRAME; + frameaddr = parse_and_eval_address (frame); + } if (varobjdebug) fprintf_unfiltered (gdb_stdlog, "Name=\"%s\", Frame=\"%s\" (0x%s), Expression=\"%s\"\n", name, frame, paddr (frameaddr), expr); - var = varobj_create (name, expr, frameaddr); + var = varobj_create (name, expr, frameaddr, var_type); if (var == NULL) error ("mi_cmd_var_create: unable to create variable object"); @@ -443,12 +449,14 @@ mi_cmd_var_update (char *command, char **argv, int argc) varobj_update_one (var); ui_out_list_end (uiout); } - return MI_CMD_DONE; + return MI_CMD_DONE; } -/* Helper for mi_cmd_var_update() */ +/* Helper for mi_cmd_var_update() Returns 0 if the update for + the variable fails (usually because the variable is out of + scope), and 1 if it succeeds. */ -static void +static int varobj_update_one (struct varobj *var) { struct varobj **changelist; @@ -457,16 +465,41 @@ varobj_update_one (struct varobj *var) nc = varobj_update (var, &changelist); - if (nc <= 0) - return; - - cc = changelist; - while (*cc != NULL) + /* nc == 0 means that nothing has changed. + nc == -1 means that an error occured in updating the variable. + nc == -2 means the variable has changed type. */ + + if (nc == 0) + return 1; + else if (nc == -1) { - ui_out_field_string (uiout, "name", varobj_get_objname (*cc)); - cc++; + ui_out_field_string (uiout, "name", varobj_get_objname(var)); + ui_out_field_string (uiout, "in_scope", "false"); + return -1; + } + else if (nc == -2) + { + ui_out_field_string (uiout, "name", varobj_get_objname (var)); + ui_out_field_string (uiout, "in_scope", "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)); + } + else + { + + cc = changelist; + while (*cc != NULL) + { + ui_out_field_string (uiout, "name", varobj_get_objname (*cc)); + ui_out_field_string (uiout, "in_scope", "true"); + ui_out_field_string (uiout, "type_changed", "false"); + cc++; + } + free (changelist); + return 1; } - free (changelist); + return 1; } /* Local variables: */ diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index fc372fd..caf80be 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2000-03-13 James Ingham <jingham@leda.cygnus.com> + + * lib/gdb.exp: Fix the gdbtk_start routine to correctly find all + the library directories. + Mon Feb 21 13:05:36 2000 Andrew Cagney <cagney@b1.cygnus.com> * configure.in (configdirs): Add sub directory gdb.mi. diff --git a/gdb/testsuite/gdb.mi/ChangeLog-mi b/gdb/testsuite/gdb.mi/ChangeLog-mi index 54cd191..b54deaa 100644 --- a/gdb/testsuite/gdb.mi/ChangeLog-mi +++ b/gdb/testsuite/gdb.mi/ChangeLog-mi @@ -1,3 +1,11 @@ +2000-03-13 James Ingham <jingham@leda.cygnus.com> + + * mi-var-block.exp: The error report from varobj_create changed + since I am now trapping parse_exp_1 errors. Change the tests to + match the new error message. + * mi-var-child.exp: Ditto. + * mi-var-cmd.exp: Ditto. + 2000-03-06 Elena Zannoni <ezannoni@kwikemart.cygnus.com> * mi-disassemble.exp: Don't assume numbers for the offset diff --git a/gdb/testsuite/gdb.mi/mi-var-block.exp b/gdb/testsuite/gdb.mi/mi-var-block.exp index 7eb473d..539a58d 100644 --- a/gdb/testsuite/gdb.mi/mi-var-block.exp +++ b/gdb/testsuite/gdb.mi/mi-var-block.exp @@ -62,7 +62,7 @@ mi_gdb_test "-var-create cb * cb" \ "create local variable cb" mi_gdb_test "-var-create foo * foo" \ - "&\"No symbol \\\\\"foo\\\\\" in current context.\\\\n\".*\\^error,msg=\"No symbol \\\\\"foo\\\\\" in current context.\"" \ + "&\"mi_cmd_var_create: unable to create variable object\\\\n\".*\\^error,msg=\"mi_cmd_var_create: unable to create variable object\"" \ "create local variable foo" # step to "foo = 123;" @@ -103,7 +103,7 @@ gdb_expect { # Test: c_variable-3.4 # Desc: check foo, cb changed mi_gdb_test "-var-update *" \ - "\\^done,changelist=\{name=\"foo\",name=\"cb\"\}" \ + "\\^done,changelist=\{name=\"foo\",in_scope=\"true\",type_changed=\"false\",name=\"cb\",in_scope=\"true\",type_changed=\"false\"\}" \ "update all vars: cb foo changed" # step to "foo = 321;" diff --git a/gdb/testsuite/gdb.mi/mi-var-child.exp b/gdb/testsuite/gdb.mi/mi-var-child.exp index 21a7cba..9aafced 100644 --- a/gdb/testsuite/gdb.mi/mi-var-child.exp +++ b/gdb/testsuite/gdb.mi/mi-var-child.exp @@ -784,7 +784,7 @@ gdb_expect { # Test: c_variable-5.2 # Desc: check that integer changed mi_gdb_test "-var-update *" \ - "\\^done,changelist=\{name=\"struct_declarations.integer\"\}" \ + "\\^done,changelist=\{name=\"struct_declarations.integer\",in_scope=\"true\",type_changed=\"false\"\}" \ "update all vars struct_declarations.integer" # Step over: @@ -805,7 +805,7 @@ gdb_expect { # Test: c_variable-5.3 # Desc: check that char_ptr changed mi_gdb_test "-var-update *" \ - "\\^done,changelist=\{name=\"struct_declarations.char_ptr\"\}" \ + "\\^done,changelist=\{name=\"struct_declarations.char_ptr\",in_scope=\"true\",type_changed=\"false\"\}" \ "update all vars struct_declarations.char_ptr" # Step over "struct_declarations.int_ptr_ptr = &foo;" @@ -822,7 +822,7 @@ gdb_expect { # Test: c_variable-5.4 # Desc: check that int_ptr_ptr and children changed mi_gdb_test "-var-update *" \ - "\\^done,changelist=\{name=\"weird->int_ptr_ptr\",name=\"weird->int_ptr_ptr.\\*weird->int_ptr_ptr\",name=\"weird->int_ptr_ptr.\\*weird->int_ptr_ptr.\\*\\*weird->int_ptr_ptr\",name=\"struct_declarations.int_ptr_ptr\",name=\"struct_declarations.int_ptr_ptr.\\*int_ptr_ptr\",name=\"struct_declarations.int_ptr_ptr.\\*int_ptr_ptr.\\*\\*int_ptr_ptr\"\}" \ + "\\^done,changelist=\{name=\"weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"weird->int_ptr_ptr.\\*weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"weird->int_ptr_ptr.\\*weird->int_ptr_ptr.\\*\\*weird->int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"struct_declarations.int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"struct_declarations.int_ptr_ptr.\\*int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"struct_declarations.int_ptr_ptr.\\*int_ptr_ptr.\\*\\*int_ptr_ptr\",in_scope=\"true\",type_changed=\"false\"\}" \ "update all vars int_ptr_ptr and children changed" # Step over "weird->long_array[0] = 1234;" @@ -839,7 +839,7 @@ gdb_expect { # Test: c_variable-5.5 # Desc: check that long_array[0] changed mi_gdb_test "-var-update *" \ - "\\^done,changelist=\{name=\"struct_declarations.long_array.0\"\}" \ + "\\^done,changelist=\{name=\"struct_declarations.long_array.0\",in_scope=\"true\",type_changed=\"false\"\}" \ "update all vars struct_declarations.long_array.0 changed" # Step over "struct_declarations.long_array[1] = 2345;" @@ -856,7 +856,7 @@ gdb_expect { # Test: c_variable-5.6 # Desc: check that long_array[1] changed mi_gdb_test "-var-update *" \ - "\\^done,changelist=\{name=\"struct_declarations.long_array.1\"\}" \ + "\\^done,changelist=\{name=\"struct_declarations.long_array.1\",in_scope=\"true\",type_changed=\"false\"\}" \ "update all vars struct_declarations.long_array.1 changed" # Step over "weird->long_array[2] = 3456;" @@ -873,7 +873,7 @@ gdb_expect { # Test: c_variable-5.7 # Desc: check that long_array[2] changed mi_gdb_test "-var-update *" \ - "\\^done,changelist=\{name=\"struct_declarations.long_array.2\"\}" \ + "\\^done,changelist=\{name=\"struct_declarations.long_array.2\",in_scope=\"true\",type_changed=\"false\"\}" \ "update all vars struct_declarations.long_array.2 changed" # Step over: @@ -897,7 +897,7 @@ gdb_expect { # Test: c_variable-5.8 # Desc: check that long_array[3-9] changed mi_gdb_test "-var-update *" \ - "\\^done,changelist=\{name=\"struct_declarations.long_array.3\",name=\"struct_declarations.long_array.4\",name=\"struct_declarations.long_array.5\",name=\"struct_declarations.long_array.6\",name=\"struct_declarations.long_array.7\",name=\"struct_declarations.long_array.8\",name=\"struct_declarations.long_array.9\"\}" \ + "\\^done,changelist=\{name=\"struct_declarations.long_array.3\",in_scope=\"true\",type_changed=\"false\",name=\"struct_declarations.long_array.4\",in_scope=\"true\",type_changed=\"false\",name=\"struct_declarations.long_array.5\",in_scope=\"true\",type_changed=\"false\",name=\"struct_declarations.long_array.6\",in_scope=\"true\",type_changed=\"false\",name=\"struct_declarations.long_array.7\",in_scope=\"true\",type_changed=\"false\",name=\"struct_declarations.long_array.8\",in_scope=\"true\",type_changed=\"false\",name=\"struct_declarations.long_array.9\",in_scope=\"true\",type_changed=\"false\"\}" \ "update all vars struct_declarations.long_array.3-9 changed" @@ -915,7 +915,7 @@ gdb_expect { # Test: c_variable-5.9 # Desc: check that func_ptr changed mi_gdb_test "-var-update *" \ - "\\^done,changelist=\{name=\"struct_declarations.func_ptr\"\}" \ + "\\^done,changelist=\{name=\"struct_declarations.func_ptr\",in_scope=\"true\",type_changed=\"false\"\}" \ "update all vars struct_declarations.func_ptr changed" # Delete all variables @@ -1185,7 +1185,7 @@ gdb_expect { # Test: c_variable-5.47 # Desc: check that psnp->char_ptr (and [0].char_ptr) changed mi_gdb_test "-var-update *" \ - "\\^done,changelist=\{name=\"psnp->ptrs.0.char_ptr\",name=\"psnp->char_ptr\",name=\"psnp->char_ptr.\\*psnp->char_ptr\",name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr\",name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr.\\*\\*\\*psnp->char_ptr\"\}" \ + "\\^done,changelist=\{name=\"psnp->ptrs.0.char_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"psnp->char_ptr.\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"psnp->char_ptr.\\*psnp->char_ptr.\\*\\*psnp->char_ptr.\\*\\*\\*psnp->char_ptr\",in_scope=\"true\",type_changed=\"false\"\}" \ "update all vars psnp->char_ptr (and 0.char_ptr) changed" # Step over "snp1.char_ptr = &c3;" @@ -1203,7 +1203,7 @@ gdb_expect { # Test: c_variable-5.48 # Desc: check that psnp->next->char_ptr (and [1].char_ptr) changed mi_gdb_test "-var-update *" \ - "\\^done,changelist=\{name=\"psnp->ptrs.0.next.char_ptr\",name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr\",name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr\",name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr.\\*\\*\\*char_ptr\"\}" \ + "\\^done,changelist=\{name=\"psnp->ptrs.0.next.char_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"psnp->ptrs.0.next.char_ptr.\\*char_ptr.\\*\\*char_ptr.\\*\\*\\*char_ptr\",in_scope=\"true\",type_changed=\"false\"\}" \ "update all vars psnp->next->char_ptr (and 1.char_ptr) changed" @@ -1222,7 +1222,7 @@ gdb_expect { # Test: c_variable-5.49 # Desc: check that psnp->next->next->char_ptr (and [2].char_ptr) changed mi_gdb_test "-var-update *" \ - "\\^done,changelist=\{name=\"psnp->ptrs.0.next.next.char_ptr\"\}" \ + "\\^done,changelist=\{name=\"psnp->ptrs.0.next.next.char_ptr\",in_scope=\"true\",type_changed=\"false\"\}" \ "update all vars psnp->next->next->char_ptr (and 2.char_ptr) changed" @@ -1240,7 +1240,7 @@ gdb_expect { # Test: c_variable-5.50 # Desc: check that psnp->long_ptr (and [0].long_ptr) changed mi_gdb_test "-var-update *" \ - "\\^done,changelist=\{name=\"psnp->ptrs.0.long_ptr\",name=\"psnp->long_ptr\",name=\"psnp->long_ptr.\\*psnp->long_ptr\",name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr\",name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr.\\*\\*\\*psnp->long_ptr\",name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr.\\*\\*\\*psnp->long_ptr.\\*\\*\\*\\*psnp->long_ptr\"\}" \ + "\\^done,changelist=\{name=\"psnp->ptrs.0.long_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"psnp->long_ptr.\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr.\\*\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\",name=\"psnp->long_ptr.\\*psnp->long_ptr.\\*\\*psnp->long_ptr.\\*\\*\\*psnp->long_ptr.\\*\\*\\*\\*psnp->long_ptr\",in_scope=\"true\",type_changed=\"false\"\}" \ "update all vars psnp->long_ptr (and 0.long_ptr) changed" @@ -1258,12 +1258,15 @@ gdb_expect { # Test: c_variable-5.51 # Desc: check that psnp->next->long_ptr (and [1].long_ptr) changed +# Why does this have a FIXME? +setup_xfail *-*-* mi_gdb_test "-var-update *" \ - "FIXME\\^done,changelist=\{name=\"psnp->ptrs.0.next.long_ptr\"\}" \ + "FIXME\\^done,changelist=\{name=\"psnp->ptrs.0.next.long_ptr\",in_scope=\"true\",type_changed=\"false\"\}" \ "update all vars psnp->next->long_ptr (and 1.long_ptr) changed" +clear_xfail *-*-* # This command produces this error message: -# &"warning: varobj_list: assertion failed - mycount <> 0\n"^M +# &"warning: varobj_list: assertion failed - mycount <> 0\n" # # Step over "snp2.long_ptr = &z3;" @@ -1281,7 +1284,7 @@ gdb_expect { # Test: c_variable-5.52 # Desc: check that psnp->next->next->long_ptr (and [2].long_ptr) changed mi_gdb_test "-var-update *" \ - "\\^done,changelist=\{name=\"psnp->ptrs.0.next.next.long_ptr\"\}" \ + "\\^done,changelist=\{name=\"psnp->ptrs.0.next.next.long_ptr\",in_scope=\"true\",type_changed=\"false\"\}" \ "update all vars psnp->next->next->long_ptr (and 2.long_ptr) changed" diff --git a/gdb/testsuite/gdb.mi/mi-var-cmd.exp b/gdb/testsuite/gdb.mi/mi-var-cmd.exp index 7b4ebcc..f1fcedd 100644 --- a/gdb/testsuite/gdb.mi/mi-var-cmd.exp +++ b/gdb/testsuite/gdb.mi/mi-var-cmd.exp @@ -59,14 +59,14 @@ mi_gdb_test "111-var-create global_simple * global_simple" \ # Desc: Create non-existent variable mi_gdb_test "112-var-create bogus_unknown_variable * bogus_unknown_variable" \ - "&\"No symbol \\\\\"bogus_unknown_variable\\\\\" in current context.\\\\n\".*112\\^error,msg=\"No symbol \\\\\"bogus_unknown_variable\\\\\" in current context.\"" \ + "&\"mi_cmd_var_create: unable to create variable object\\\\n\".*112\\^error,msg=\"mi_cmd_var_create: unable to create variable object\"" \ "create non-existent variable" # Test: c_variable-1.3 # Desc: Create out of scope variable mi_gdb_test "113-var-create argc * argc" \ - "&\"No symbol \\\\\"argc\\\\\" in current context.\\\\n\".*113\\^error,msg=\"No symbol \\\\\"argc\\\\\" in current context.\"" \ + "&\"mi_cmd_var_create: unable to create variable object\\\\n\".*113\\^error,msg=\"mi_cmd_var_create: unable to create variable object\"" \ "create out of scope variable" mi_gdb_test "200-break-insert do_locals_tests" \ @@ -192,7 +192,7 @@ gdb_expect { # Test: c_variable-2.2 # Desc: check whether only linteger changed values mi_gdb_test "-var-update *" \ - "\\^done,changelist=\{name=\"linteger\"\}" \ + "\\^done,changelist=\{name=\"linteger\",in_scope=\"true\",type_changed=\"false\"\}" \ "update all vars: linteger changed" # Step over "lpinteger = &linteger;" @@ -209,7 +209,7 @@ gdb_expect { # Test: c_variable-2.3 # Desc: check whether only lpinteger changed mi_gdb_test "-var-update *" \ - "\\^done,changelist=\{name=\"lpinteger\"\}" \ + "\\^done,changelist=\{name=\"lpinteger\",in_scope=\"true\",type_changed=\"false\"\}" \ "update all vars: lpinteger changed" # Step over "lcharacter = 'a';" @@ -226,7 +226,7 @@ gdb_expect { # Test: c_variable-2.4 # Desc: check whether only lcharacter changed mi_gdb_test "-var-update *" \ - "\\^done,changelist=\{name=\"lcharacter\"\}" \ + "\\^done,changelist=\{name=\"lcharacter\",in_scope=\"true\",type_changed=\"false\"\}" \ "update all vars: lcharacter changed" # Step over "lpcharacter = &lcharacter;" @@ -243,7 +243,7 @@ gdb_expect { # Test: c_variable-2.5 # Desc: check whether only lpcharacter changed mi_gdb_test "-var-update *" \ - "\\^done,changelist=\{name=\"lpcharacter\"\}" \ + "\\^done,changelist=\{name=\"lpcharacter\",in_scope=\"true\",type_changed=\"false\"\}" \ "update all vars: lpcharacter changed" @@ -272,7 +272,7 @@ gdb_expect { # Desc: check whether llong, lplong, lfloat, lpfloat, ldouble, lpdouble, lsimple.integer, # lsimple.unsigned_character lsimple.integer lsimple.character changed mi_gdb_test "-var-update *" \ - "\\^done,changelist=\{name=\"lsimple.integer\",name=\"lsimple->integer\",name=\"lsimple.character\",name=\"lpdouble\",name=\"ldouble\",name=\"lpfloat\",name=\"lfloat\",name=\"lplong\",name=\"llong\"\}" \ + "\\^done,changelist=\{name=\"lsimple.integer\",in_scope=\"true\",type_changed=\"false\",name=\"lsimple->integer\",in_scope=\"true\",type_changed=\"false\",name=\"lsimple.character\",in_scope=\"true\",type_changed=\"false\",name=\"lpdouble\",in_scope=\"true\",type_changed=\"false\",name=\"ldouble\",in_scope=\"true\",type_changed=\"false\",name=\"lpfloat\",in_scope=\"true\",type_changed=\"false\",name=\"lfloat\",in_scope=\"true\",type_changed=\"false\",name=\"lplong\",in_scope=\"true\",type_changed=\"false\",name=\"llong\",in_scope=\"true\",type_changed=\"false\"\}" \ "update all vars: many changed" # Step over: @@ -294,7 +294,7 @@ gdb_expect { # Test: c_variable-2.7 # Desc: check whether (lsimple.signed_character, lsimple.char_ptr) lpsimple, func changed mi_gdb_test "-var-update *" \ - "\\^done,changelist=\{name=\"func\",name=\"lpsimple\"\}" \ + "\\^done,changelist=\{name=\"func\",in_scope=\"true\",type_changed=\"false\",name=\"lpsimple\",in_scope=\"true\",type_changed=\"false\"\}" \ "update all vars: func and lpsimple changed" # Step over @@ -323,7 +323,7 @@ gdb_expect { # Note: this test also checks that lpsimple->integer and lsimple.integer have # changed (they are the same) mi_gdb_test "-var-update *" \ - "\\^done,changelist=\{name=\"lsimple.integer\",name=\"lsimple->integer\",name=\"lsimple.character\",name=\"ldouble\",name=\"lfloat\",name=\"llong\",name=\"lcharacter\",name=\"linteger\"\}" \ + "\\^done,changelist=\{name=\"lsimple.integer\",in_scope=\"true\",type_changed=\"false\",name=\"lsimple->integer\",in_scope=\"true\",type_changed=\"false\",name=\"lsimple.character\",in_scope=\"true\",type_changed=\"false\",name=\"ldouble\",in_scope=\"true\",type_changed=\"false\",name=\"lfloat\",in_scope=\"true\",type_changed=\"false\",name=\"llong\",in_scope=\"true\",type_changed=\"false\",name=\"lcharacter\",in_scope=\"true\",type_changed=\"false\",name=\"linteger\",in_scope=\"true\",type_changed=\"false\"\}" \ "update all vars: func and lpsimple changed" @@ -454,7 +454,7 @@ mi_gdb_test "-var-create l * l" \ # Test: c_variable-2.11 # Desc: create do_locals_tests local in subroutine1 mi_gdb_test "-var-create linteger * linteger" \ - "&\"No symbol \\\\\"linteger\\\\\" in current context.\\\\n\".*\\^error,msg=\"No symbol \\\\\"linteger\\\\\" in current context.\"" \ + "&\"mi_cmd_var_create: unable to create variable object\\\\n\".*\\^error,msg=\"mi_cmd_var_create: unable to create variable object\"" \ "create linteger" send_gdb "-exec-step\n" @@ -471,10 +471,14 @@ gdb_expect { # Desc: change global_simple.integer # Note: This also tests whether we are reporting changes in structs properly. # gdb normally would say that global_simple has changed, but we -# special case that, since it is not what a human expects to see. +# special case that, since it is not what a human expects to +# see. + +setup_xfail *-*-* mi_gdb_test "-var-update *" \ "\\^done,changelist=\{FIXME: WHAT IS CORRECT HERE\}" \ "update all vars: changed FIXME" +clear_xfail *-*-* send_gdb "-exec-step\n" gdb_expect { @@ -487,7 +491,7 @@ gdb_expect { # Test: c_variable-2.13 # Desc: change subroutine1 local i mi_gdb_test "-var-update *" \ - "\\^done,changelist=\{name=\"i\"\}" \ + "\\^done,changelist=\{name=\"i\",in_scope=\"true\",type_changed=\"false\"\}" \ "update all vars: i changed" send_gdb "-exec-step\n" @@ -501,7 +505,7 @@ gdb_expect { # Test: c_variable-2.14 # Desc: change do_locals_tests local llong mi_gdb_test "-var-update *" \ - "\\^done,changelist=\{name=\"llong\"\}" \ + "\\^done,changelist=\{name=\"llong\",in_scope=\"true\",type_changed=\"false\"\}" \ "update all vars: llong changed" send_gdb "-exec-next\n" @@ -515,8 +519,8 @@ gdb_expect { # Test: c_variable-2.15 # Desc: check for out of scope subroutine1 locals mi_gdb_test "-var-update *" \ - "\\^done,changelist=\{\}" \ - "update all vars: none changed" + "\\^done,changelist=\{name=\"l\",in_scope=\"false\",name=\"i\",in_scope=\"false\"\}" \ + "update all vars: all now out of scope" # Done with locals/globals tests. Erase all variables #delete_all_variables diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp index 1a5ecc8..191bf18 100644 --- a/gdb/testsuite/lib/gdb.exp +++ b/gdb/testsuite/lib/gdb.exp @@ -1617,29 +1617,31 @@ proc gdbtk_start {test} { } } + set wd [pwd] - cd [file join $srcdir .. gdbtk library] + cd $srcdir + set abs_srcdir [pwd] + cd [file join $abs_srcdir .. gdbtk library] set env(GDBTK_LIBRARY) [pwd] - cd [file join $srcdir .. .. tcl library] + cd [file join $abs_srcdir .. .. tcl library] set env(TCL_LIBRARY) [pwd] - cd [file join $srcdir .. .. tk library] + cd [file join $abs_srcdir .. .. tk library] set env(TK_LIBRARY) [pwd] - cd [file join $srcdir .. .. tix library] + cd [file join $abs_srcdir .. .. tix library] set env(TIX_LIBRARY) [pwd] - cd [file join $srcdir .. .. itcl itcl library] + cd [file join $abs_srcdir .. .. itcl itcl library] set env(ITCL_LIBRARY) [pwd] - cd [file join .. $srcdir .. .. libgui library] + cd [file join .. $abs_srcdir .. .. libgui library] set env(CYGNUS_GUI_LIBRARY) [pwd] cd $wd - cd [file join $srcdir $subdir] + cd [file join $abs_srcdir $subdir] set env(DEFS) [file join [pwd] defs] cd $wd cd [file join $objdir $subdir] set env(OBJDIR) [pwd] cd $wd - cd $srcdir - set env(SRCDIR) [pwd] - cd $wd + + set env(SRCDIR) $abs_srcdir set env(GDBTK_VERBOSE) 1 set env(GDBTK_LOGFILE) [file join $objdir gdb.log] set env(GDBTK_TEST_RUNNING) 1 diff --git a/gdb/varobj.c b/gdb/varobj.c index f0740c6..e2a2419 100644 --- a/gdb/varobj.c +++ b/gdb/varobj.c @@ -56,6 +56,10 @@ struct varobj_root /* The frame for this expression */ CORE_ADDR frame; + /* If 1, "update" always recomputes the frame & valid block + using the currently selected frame. */ + int use_selected_frame; + /* Language info for this variable and its children */ struct language_specific *lang; @@ -204,7 +208,8 @@ static char *name_of_variable PARAMS ((struct varobj *)); static char *name_of_child PARAMS ((struct varobj *, int)); -static value_ptr value_of_root PARAMS ((struct varobj * var)); +static value_ptr value_of_root PARAMS ((struct varobj ** var_handle, + int *)); static value_ptr value_of_child PARAMS ((struct varobj * parent, int index)); @@ -224,7 +229,7 @@ static char *c_name_of_variable PARAMS ((struct varobj * parent)); static char *c_name_of_child PARAMS ((struct varobj * parent, int index)); -static value_ptr c_value_of_root PARAMS ((struct varobj * var)); +static value_ptr c_value_of_root PARAMS ((struct varobj ** var_handle)); static value_ptr c_value_of_child PARAMS ((struct varobj * parent, int index)); @@ -244,7 +249,7 @@ static char *cplus_name_of_variable PARAMS ((struct varobj * parent)); static char *cplus_name_of_child PARAMS ((struct varobj * parent, int index)); -static value_ptr cplus_value_of_root PARAMS ((struct varobj * var)); +static value_ptr cplus_value_of_root PARAMS ((struct varobj ** var_handle)); static value_ptr cplus_value_of_child PARAMS ((struct varobj * parent, int index)); @@ -262,7 +267,7 @@ static char *java_name_of_variable PARAMS ((struct varobj * parent)); static char *java_name_of_child PARAMS ((struct varobj * parent, int index)); -static value_ptr java_value_of_root PARAMS ((struct varobj * var)); +static value_ptr java_value_of_root PARAMS ((struct varobj ** var_handle)); static value_ptr java_value_of_child PARAMS ((struct varobj * parent, int index)); @@ -290,7 +295,7 @@ struct language_specific char *(*name_of_child) PARAMS ((struct varobj * parent, int index)); /* The value_ptr of the root variable ROOT. */ - value_ptr (*value_of_root) PARAMS ((struct varobj * root)); + value_ptr (*value_of_root) PARAMS ((struct varobj ** root_handle)); /* The value_ptr of the INDEX'th child of PARENT. */ value_ptr (*value_of_child) PARAMS ((struct varobj * parent, int index)); @@ -401,7 +406,8 @@ static struct vlist **varobj_table; struct varobj * varobj_create (char *objname, - char *expression, CORE_ADDR frame) + char *expression, CORE_ADDR frame, + enum varobj_type type) { struct varobj *var; struct frame_info *fi, *old_fi; @@ -421,19 +427,28 @@ varobj_create (char *objname, of the variable's data as possible */ /* Allow creator to specify context of variable */ - if (frame == (CORE_ADDR) -1) + if ((type == USE_CURRENT_FRAME) + || (type == USE_SELECTED_FRAME)) fi = selected_frame; else fi = find_frame_addr_in_frame_chain (frame); + /* frame = -2 means always use selected frame */ + if (type == USE_SELECTED_FRAME) + var->root->use_selected_frame = 1; + block = NULL; if (fi != NULL) block = get_frame_block (fi); p = expression; innermost_block = NULL; - /* Callee may longjump */ - var->root->exp = parse_exp_1 (&p, block, 0); + /* Wrap the call to parse expression, so we can + return a sensible error. */ + if (!gdb_parse_exp_1 (&p, block, 0, &var->root->exp)) + { + return NULL; + } /* Don't allow variables to be created for types. */ if (var->root->exp->elts[0].opcode == OP_TYPE) @@ -486,7 +501,10 @@ varobj_create (char *objname, select_frame (old_fi, -1); } - if (var != NULL) + /* If the variable object name is null, that means this + is a temporary variable, so don't install it. */ + + if ((var != NULL) && (objname != NULL)) { var->obj_name = savestring (objname, strlen (objname)); @@ -845,6 +863,10 @@ varobj_list (struct varobj ***varlist) expression to see if it's changed. Then go all the way through its children, reconstructing them and noting if they've changed. + Return value: + -1 if there was an error updating the varobj + -2 if the type changed + Otherwise it is the number of children + parent changed Only root variables can be updated... */ @@ -852,6 +874,7 @@ int varobj_update (struct varobj *var, struct varobj ***changelist) { int changed = 0; + int type_changed; int i; int vleft; int error2; @@ -878,19 +901,27 @@ varobj_update (struct varobj *var, struct varobj ***changelist) /* Update the root variable. value_of_root can return NULL if the variable is no longer around, i.e. we stepped out of - the frame in which a local existed. */ - new = value_of_root (var); + the frame in which a local existed. We are letting the + value_of_root variable dispose of the varobj if the type + has changed. */ + type_changed = 1; + new = value_of_root (&var, &type_changed); if (new == NULL) - return -1; + { + var->error = 1; + return -1; + } /* Initialize a stack for temporary results */ vpush (&result, NULL); - if (!my_value_equal (var->value, new, &error2)) + if (type_changed || !my_value_equal (var->value, new, &error2)) { /* Note that it's changed There a couple of exceptions here, - though. We don't want some types to be reported as "changed". */ - if (type_changeable (var)) + though. We don't want some types to be reported as + "changed". The exception to this is if this is a + "use_selected_frame" varobj, and its type has changed. */ + if (type_changed || type_changeable (var)) { vpush (&result, var); changed++; @@ -984,7 +1015,10 @@ varobj_update (struct varobj *var, struct varobj ***changelist) /* Restore selected frame */ select_frame (old_fi, -1); - return changed; + if (type_changed) + return -2; + else + return changed; } @@ -1039,9 +1073,9 @@ delete_variable_1 (resultp, delcountp, var, return; /* Otherwise, add it to the list of deleted ones and proceed to do so */ - if (var->obj_name == NULL) - warning ("Assertion failed: NULL var->obj_name unexpectdly found"); - else + /* If the name is null, this is a temporary variable, that has not + yet been installed, don't report it, it belongs to the caller... */ + if (var->obj_name != NULL) { cppush (resultp, strdup (var->obj_name)); *delcountp = *delcountp + 1; @@ -1057,8 +1091,9 @@ delete_variable_1 (resultp, delcountp, var, { remove_child_from_parent (var->parent, var); } - - uninstall_variable (var); + + if (var->obj_name != NULL) + uninstall_variable (var); /* Free memory associated with this variable */ free_variable (var); @@ -1315,6 +1350,7 @@ new_root_variable (void) var->root->exp = NULL; var->root->valid_block = NULL; var->root->frame = (CORE_ADDR) -1; + var->root->use_selected_frame = 0; var->root->rootvar = NULL; return var; @@ -1578,12 +1614,74 @@ name_of_child (var, index) return (*var->root->lang->name_of_child) (var, index); } -/* What is the value_ptr of the root variable VAR? */ +/* What is the value_ptr of the root variable VAR? + TYPE_CHANGED controls what to do if the type of a + use_selected_frame = 1 variable changes. On input, + TYPE_CHANGED = 1 means discard the old varobj, and replace + it with this one. TYPE_CHANGED = 0 means leave it around. + NB: In both cases, var_handle will point to the new varobj, + so if you use TYPE_CHANGED = 0, you will have to stash the + old varobj pointer away somewhere before calling this. + On return, TYPE_CHANGED will be 1 if the type has changed, and + 0 otherwise. */ static value_ptr -value_of_root (var) - struct varobj *var; +value_of_root (var_handle, type_changed) + struct varobj ** var_handle; + int *type_changed; { - return (*var->root->lang->value_of_root) (var); + struct varobj *var; + + if (var_handle == NULL) + return NULL; + + var = *var_handle; + + /* This should really be an exception, since this should + only get called with a root variable. */ + + if (var->root->rootvar != var) + return NULL; + + if (var->root->use_selected_frame) + { + struct varobj *tmp_var; + char *old_type, *new_type; + old_type = varobj_get_type (var); + tmp_var = varobj_create (NULL, var->name, (CORE_ADDR) 0, + USE_SELECTED_FRAME); + if (tmp_var == NULL) + { + return NULL; + } + new_type = varobj_get_type (tmp_var); + if (strcmp(old_type, new_type) == 0) + { + varobj_delete (tmp_var, NULL, 0); + *type_changed = 0; + } + else + { + if (*type_changed) + { + tmp_var->obj_name = + savestring (var->obj_name, strlen (var->obj_name)); + uninstall_variable (var); + } + else + { + tmp_var->obj_name = varobj_gen_name (); + } + install_variable (tmp_var); + *var_handle = tmp_var; + *type_changed = 1; + } + } + else + { + *type_changed = 0; + } + + return (*var->root->lang->value_of_root) (var_handle); } /* What is the value_ptr for the INDEX'th child of PARENT? */ @@ -1790,38 +1888,51 @@ c_name_of_child (parent, index) } static value_ptr -c_value_of_root (var) - struct varobj *var; +c_value_of_root (var_handle) + struct varobj **var_handle; { value_ptr new_val; + struct varobj *var = *var_handle; struct frame_info *fi; int within_scope; + /* Only root variables can be updated... */ + if (var->root->rootvar != var) + /* Not a root var */ + return NULL; + + /* Determine whether the variable is still around. */ if (var->root->valid_block == NULL) within_scope = 1; else { reinit_frame_cache (); + + fi = find_frame_addr_in_frame_chain (var->root->frame); + within_scope = fi != NULL; /* FIXME: select_frame could fail */ if (within_scope) select_frame (fi, -1); } - + if (within_scope) { - /* We need to catch errors here, because if evaluate expression fails - we just want to make val->error = 1 and go on */ + /* We need to catch errors here, because if evaluate + expression fails we just want to make val->error = 1 and + go on */ if (gdb_evaluate_expression (var->root->exp, &new_val)) { if (VALUE_LAZY (new_val)) { - /* We need to catch errors because if value_fetch_lazy fails we - still want to continue (after making val->error = 1) */ - /* FIXME: Shouldn't be using VALUE_CONTENTS? The comment on - value_fetch_lazy() says it is only called from the macro... */ + /* We need to catch errors because if + value_fetch_lazy fails we still want to continue + (after making val->error = 1) */ + /* FIXME: Shouldn't be using VALUE_CONTENTS? The + comment on value_fetch_lazy() says it is only + called from the macro... */ if (!gdb_value_fetch_lazy (new_val)) var->error = 1; else @@ -1830,7 +1941,7 @@ c_value_of_root (var) } else var->error = 1; - + release_value (new_val); return new_val; } @@ -2194,10 +2305,10 @@ cplus_name_of_child (parent, index) } static value_ptr -cplus_value_of_root (var) - struct varobj *var; +cplus_value_of_root (var_handle) + struct varobj **var_handle; { - return c_value_of_root (var); + return c_value_of_root (var_handle); } static value_ptr @@ -2367,10 +2478,10 @@ java_name_of_child (parent, index) } static value_ptr -java_value_of_root (var) - struct varobj *var; +java_value_of_root (var_handle) + struct varobj **var_handle; { - return cplus_value_of_root (var); + return cplus_value_of_root (var_handle); } static value_ptr diff --git a/gdb/varobj.h b/gdb/varobj.h index 28c5fac..e5e3254 100644 --- a/gdb/varobj.h +++ b/gdb/varobj.h @@ -32,6 +32,13 @@ enum varobj_display_formats FORMAT_OCTAL /* Octal display */ }; +enum varobj_type + { + USE_SPECIFIED_FRAME, /* Use the frame passed to varobj_create */ + USE_CURRENT_FRAME, /* Use the current frame */ + USE_SELECTED_FRAME /* Always reevaluate in selected frame */ + }; + /* String representations of gdb's format codes (defined in varobj.c) */ extern char *varobj_format_string[]; @@ -50,7 +57,8 @@ struct varobj; /* API functions */ extern struct varobj *varobj_create (char *objname, - char *expression, CORE_ADDR frame); + char *expression, CORE_ADDR frame, + enum varobj_type type); extern char *varobj_gen_name (void); diff --git a/gdb/wrapper.c b/gdb/wrapper.c index be7d4e2..ea43fd9 100644 --- a/gdb/wrapper.c +++ b/gdb/wrapper.c @@ -33,6 +33,10 @@ struct gdb_wrapper_arguments char *args[10]; }; +int gdb_parse_exp_1 PARAMS ((char **, struct block *, + int, struct expression **)); +int wrap_parse_exp_1 PARAMS ((char *)); + int gdb_evaluate_expression PARAMS ((struct expression *, value_ptr *)); int wrap_evaluate_expression PARAMS ((char *)); @@ -46,6 +50,42 @@ int gdb_value_ind PARAMS ((value_ptr val, value_ptr * rval)); int wrap_value_ind PARAMS ((char *opaque_arg)); int +gdb_parse_exp_1 (stringptr, block, comma, expression) + char **stringptr; + struct block *block; + int comma; + struct expression **expression; +{ + struct gdb_wrapper_arguments args; + args.args[0] = (char *) stringptr; + args.args[1] = (char *) block; + args.args[2] = (char *) comma; + + if (!catch_errors ((catch_errors_ftype *) wrap_parse_exp_1, &args, + "", RETURN_MASK_ERROR)) + { + /* An error occurred */ + return 0; + } + + *expression = (struct expression *) args.result; + return 1; + +} + +int +wrap_parse_exp_1 (argptr) + char *argptr; +{ + struct gdb_wrapper_arguments *args + = (struct gdb_wrapper_arguments *) argptr; + args->result = (char *) parse_exp_1((char **) args->args[0], + (struct block *) args->args[1], + (int) args->args[2]); + return 1; +} + +int gdb_evaluate_expression (exp, value) struct expression *exp; value_ptr *value; @@ -163,3 +203,4 @@ wrap_value_ind (opaque_arg) (args)->result = (char *) value_ind (val); return 1; } + diff --git a/gdb/wrapper.h b/gdb/wrapper.h index f4303b2..401cad8 100644 --- a/gdb/wrapper.h +++ b/gdb/wrapper.h @@ -22,6 +22,10 @@ /* Use this struct used to pass arguments to wrapper routines. */ struct gdb_wrapper_arguments; +extern int gdb_parse_exp_1 PARAMS ((char **, struct block *, + int, struct expression **)); +extern int wrap_parse_exp_1 PARAMS ((char *)); + extern int gdb_evaluate_expression PARAMS ((struct expression *, value_ptr *)); extern int wrap_evaluate_expression PARAMS ((char *)); |