diff options
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/ChangeLog | 8 | ||||
-rw-r--r-- | gdb/Makefile.in | 3 | ||||
-rw-r--r-- | gdb/eval.c | 24 | ||||
-rw-r--r-- | gdb/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gdb/testsuite/gdb.mi/mi-var-cmd.exp | 43 | ||||
-rw-r--r-- | gdb/varobj.c | 2 |
6 files changed, 80 insertions, 4 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index e5b5743ce17..854e5735d7d 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,13 @@ 2007-01-04 Daniel Jacobowitz <dan@codesourcery.com> + * Makefile.in (eval.o): Update dependencies. + * eval.c: Include "ui-out.h" and "exceptions.h". + (evaluate_subexp_standard): Use TRY_CATCH around value_of_variable. + Use value_zero if an error occurs when avoiding side effects. + * varobj.c (c_value_of_root): Initialize new_val. + +2007-01-04 Daniel Jacobowitz <dan@codesourcery.com> + * varobj.c (varobj_list_children): Stop if the number of children is unknown. (c_number_of_children): diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 491e7d48442..928cd771d0a 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -1968,7 +1968,8 @@ environ.o: environ.c $(defs_h) $(environ_h) $(gdb_string_h) eval.o: eval.c $(defs_h) $(gdb_string_h) $(symtab_h) $(gdbtypes_h) \ $(value_h) $(expression_h) $(target_h) $(frame_h) $(language_h) \ $(f_lang_h) $(cp_abi_h) $(infcall_h) $(objc_lang_h) $(block_h) \ - $(parser_defs_h) $(cp_support_h) $(gdb_assert_h) + $(parser_defs_h) $(cp_support_h) $(gdb_assert_h) $(exceptions_h) \ + $(uiout_h) event-loop.o: event-loop.c $(defs_h) $(event_loop_h) $(event_top_h) \ $(gdb_string_h) $(exceptions_h) $(gdb_assert_h) $(gdb_select_h) event-top.o: event-top.c $(defs_h) $(top_h) $(inferior_h) $(target_h) \ diff --git a/gdb/eval.c b/gdb/eval.c index 1a3d72a5478..4954e9fbaf1 100644 --- a/gdb/eval.c +++ b/gdb/eval.c @@ -37,6 +37,8 @@ #include "block.h" #include "parser-defs.h" #include "cp-support.h" +#include "ui-out.h" +#include "exceptions.h" #include "gdb_assert.h" @@ -469,8 +471,26 @@ evaluate_subexp_standard (struct type *expect_type, value_rtti_target_type () if we are dealing with a pointer or reference to a base class and print object is on. */ - return value_of_variable (exp->elts[pc + 2].symbol, - exp->elts[pc + 1].block); + { + volatile struct gdb_exception except; + struct value *ret = NULL; + + TRY_CATCH (except, RETURN_MASK_ERROR) + { + ret = value_of_variable (exp->elts[pc + 2].symbol, + exp->elts[pc + 1].block); + } + + if (except.reason < 0) + { + if (noside == EVAL_AVOID_SIDE_EFFECTS) + ret = value_zero (SYMBOL_TYPE (exp->elts[pc + 2].symbol), not_lval); + else + throw_exception (except); + } + + return ret; + } case OP_LAST: (*pos) += 2; diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 6966dceb6a6..d8b8c3531a3 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,5 +1,9 @@ 2007-01-04 Daniel Jacobowitz <dan@codesourcery.com> + * gdb.mi/mi-var-cmd.exp: Add tests for unreadable varobjs. + +2007-01-04 Daniel Jacobowitz <dan@codesourcery.com> + * lib/mi-support.exp (mi_runto_helper): Expect two prompts when continuing. diff --git a/gdb/testsuite/gdb.mi/mi-var-cmd.exp b/gdb/testsuite/gdb.mi/mi-var-cmd.exp index d7cd4e99a0b..9dfcc52d1c4 100644 --- a/gdb/testsuite/gdb.mi/mi-var-cmd.exp +++ b/gdb/testsuite/gdb.mi/mi-var-cmd.exp @@ -586,5 +586,48 @@ mi_gdb_test "-var-update selected_a" \ "\\^done,changelist=\\\[\{name=\"selected_a\",in_scope=\"true\",new_type=\"int\",new_num_children=\"0\"\}\\\]" \ "update selected_a in do_special_tests" +# Test whether bad varobjs crash GDB. + +# A varobj we fail to read during -var-update should be considered +# out of scope. +mi_gdb_test "-var-create null_ptr * **0" \ + {\^done,name="null_ptr",numchild="0",type="int"} \ + "create null_ptr" + +# Allow this to succeed, if address zero is readable, although it +# will not test what it was meant to. Most important is that GDB +# does not crash. +mi_gdb_test "-var-update null_ptr" \ + {\^done,changelist=\[{.*}\]} \ + "update null_ptr" + +mi_gdb_test "-var-delete null_ptr" \ + "\\^done,ndeleted=\"1\"" \ + "delete null_ptr" + +# When we fail to read a varobj created from a named variable, +# we evaluate its type instead. Make sure that doesn't blow +# up by trying to read it again. We can use _end when not running +# the program to simulate an unreadable variable, if this platform +# provides _end, but cope if it's missing. + +mi_gdb_test "kill" \ + {&"kill\\n".*\^done} \ + "kill program before endvar" + +mi_gdb_test "-var-create endvar * _end" \ + {(\^done,name="endvar",numchild="0",type=".*"|&".*unable to.*".*\^error,msg=".*")} \ + "create endvar" + +# Allow this to succeed whether the value is readable, unreadable, or +# missing. Most important is that GDB does not crash. +mi_gdb_test "-var-update endvar" \ + {(\^done,changelist=\[.*\]|^".*".*\^error,msg=".*not found")} \ + "update endvar" + +mi_gdb_test "-var-delete endvar" \ + "\\^done,ndeleted=\"1\"" \ + "delete endvar" + mi_gdb_exit return 0 diff --git a/gdb/varobj.c b/gdb/varobj.c index a9f8ee07984..33cea73a863 100644 --- a/gdb/varobj.c +++ b/gdb/varobj.c @@ -1908,7 +1908,7 @@ c_name_of_child (struct varobj *parent, int index) static struct value * c_value_of_root (struct varobj **var_handle) { - struct value *new_val; + struct value *new_val = NULL; struct varobj *var = *var_handle; struct frame_info *fi; int within_scope; |