summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2009-01-01 22:02:03 +0000
committerPedro Alves <palves@redhat.com>2009-01-01 22:02:03 +0000
commitccc57cf9e6782a19d8bccb1fdd0d02dd6ab98702 (patch)
tree8f5a92c1161105aae211fbdd06369748a2eee8e3
parent023b0f5cefb067d6338e9bfd2987e4ed54b8b379 (diff)
downloadbinutils-gdb-ccc57cf9e6782a19d8bccb1fdd0d02dd6ab98702.tar.gz
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. 2009-01-01 Pedro Alves <pedro@codesourcery.com> PR breakpoints/9681: * gdb.base/watchpoint.exp: Add regression test.
-rw-r--r--gdb/ChangeLog8
-rw-r--r--gdb/breakpoint.c24
-rw-r--r--gdb/corefile.c28
-rw-r--r--gdb/exceptions.h3
-rw-r--r--gdb/testsuite/ChangeLog5
-rw-r--r--gdb/testsuite/gdb.base/watchpoint.exp12
6 files changed, 60 insertions, 20 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index a9f0b10c47a..edce418c4f9 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 30c89bd1db9..83118bc793e 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 af2d1a3633b..c477660e54c 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 b6d4e12cdbe..6616dbf1fe2 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 7244a1da771..3b9c4b459ef 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 9935ef883dc..6557cba4a4c 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" {