diff options
-rw-r--r-- | gdb/ChangeLog | 8 | ||||
-rw-r--r-- | gdb/breakpoint.c | 24 | ||||
-rw-r--r-- | gdb/corefile.c | 28 | ||||
-rw-r--r-- | gdb/exceptions.h | 3 | ||||
-rw-r--r-- | gdb/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/watchpoint.exp | 12 |
6 files changed, 60 insertions, 20 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index a9f0b10..edce418 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,11 @@ +2009-01-01 Pedro Alves <pedro@codesourcery.com> + + PR breakpoints/9681: + * exceptions.h (enum errors): New error type, MEMORY_ERROR. + * corefile.c (memory_error): Rewrite to throw a MEMORY_ERROR. + * breakpoint.c (fetch_watchpoint_value): Ignore MEMORY_ERRORs, but + retrow all other exceptions. + 2008-12-31 Pedro Alves <pedro@codesourcery.com> PR gdb/8812: diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 30c89bd..83118bc 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -755,7 +755,7 @@ is_hardware_watchpoint (struct breakpoint *bpt) in *VAL_CHAIN. RESULTP and VAL_CHAIN may be NULL if the caller does not need them. - If an error occurs while evaluating the expression, *RESULTP will + If a memory error occurs while evaluating the expression, *RESULTP will be set to NULL. *RESULTP may be a lazy value, if the result could not be read from memory. It is used to determine whether a value is user-specified (we should watch the whole value) or intermediate @@ -776,6 +776,7 @@ fetch_watchpoint_value (struct expression *exp, struct value **valp, struct value **resultp, struct value **val_chain) { struct value *mark, *new_mark, *result; + volatile struct gdb_exception ex; *valp = NULL; if (resultp) @@ -786,7 +787,26 @@ fetch_watchpoint_value (struct expression *exp, struct value **valp, /* Evaluate the expression. */ mark = value_mark (); result = NULL; - gdb_evaluate_expression (exp, &result); + + TRY_CATCH (ex, RETURN_MASK_ALL) + { + result = evaluate_expression (exp); + } + if (ex.reason < 0) + { + /* Ignore memory errors, we want watchpoints pointing at + inaccessible memory to still be created; otherwise, throw the + error to some higher catcher. */ + switch (ex.error) + { + case MEMORY_ERROR: + break; + default: + throw_exception (ex); + break; + } + } + new_mark = value_mark (); if (mark == new_mark) return; diff --git a/gdb/corefile.c b/gdb/corefile.c index af2d1a3..c477660 100644 --- a/gdb/corefile.c +++ b/gdb/corefile.c @@ -205,30 +205,22 @@ Use the \"file\" or \"exec-file\" command.")); } -/* Report a memory error with error(). */ +/* Report a memory error by throwing a MEMORY_ERROR error. */ void memory_error (int status, CORE_ADDR memaddr) { - struct ui_file *tmp_stream = mem_fileopen (); - make_cleanup_ui_file_delete (tmp_stream); - if (status == EIO) - { - /* Actually, address between memaddr and memaddr + len - was out of bounds. */ - fprintf_unfiltered (tmp_stream, "Cannot access memory at address "); - fputs_filtered (paddress (memaddr), tmp_stream); - } + /* Actually, address between memaddr and memaddr + len was out of + bounds. */ + throw_error (MEMORY_ERROR, + _("Cannot access memory at address %s"), + paddress (memaddr)); else - { - fprintf_filtered (tmp_stream, "Error accessing memory address "); - fputs_filtered (paddress (memaddr), tmp_stream); - fprintf_filtered (tmp_stream, ": %s.", - safe_strerror (status)); - } - - error_stream (tmp_stream); + throw_error (MEMORY_ERROR, + _("Error accessing memory address %s: %s."), + paddress (memaddr), + safe_strerror (status)); } /* Same as target_read_memory, but report an error if can't read. */ diff --git a/gdb/exceptions.h b/gdb/exceptions.h index b6d4e12..6616dbf 100644 --- a/gdb/exceptions.h +++ b/gdb/exceptions.h @@ -72,6 +72,9 @@ enum errors { /* Problem parsing an XML document. */ XML_PARSE_ERROR, + /* Error accessing memory. */ + MEMORY_ERROR, + /* Add more errors here. */ NR_ERRORS }; diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 7244a1d..3b9c4b4 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2009-01-01 Pedro Alves <pedro@codesourcery.com> + + PR breakpoints/9681: + * gdb.base/watchpoint.exp: Add regression test. + 2008-12-31 Pedro Alves <pedro@codesourcery.com> * gdb.threads/attach-into-signal.exp: Don't use diff --git a/gdb/testsuite/gdb.base/watchpoint.exp b/gdb/testsuite/gdb.base/watchpoint.exp index 9935ef8..6557cba 100644 --- a/gdb/testsuite/gdb.base/watchpoint.exp +++ b/gdb/testsuite/gdb.base/watchpoint.exp @@ -649,6 +649,18 @@ proc test_inaccessible_watchpoint {} { # valid) memory. if [runto func4] then { + # Make sure we only allow memory access errors. + set msg "watchpoint refused to insert on nonexistent struct member" + gdb_test_multiple "watch struct1.nosuchmember" $msg { + -re ".*atchpoint \[0-9\]+: struct1.nosuchmember.*$gdb_prompt $" { + # PR breakpoints/9681 + fail $msg + } + -re "There is no member named nosuchmember\\..*$gdb_prompt $" { + pass $msg + } + } + gdb_test "watch *global_ptr" ".*atchpoint \[0-9\]+: \\*global_ptr" gdb_test "next" ".*global_ptr = buf.*" gdb_test_multiple "next" "next over ptr init" { |