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.
This commit is contained in:
Pedro Alves 2009-01-01 22:02:03 +00:00
parent 023b0f5cef
commit ccc57cf9e6
6 changed files with 60 additions and 20 deletions

View File

@ -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:

View File

@ -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;

View File

@ -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. */

View File

@ -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
};

View File

@ -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

View File

@ -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" {