2009-01-01 Pedro Alves <pedro@codesourcery.com>
authorPedro Alves <palves@redhat.com>
Thu, 1 Jan 2009 22:02:03 +0000 (22:02 +0000)
committerPedro Alves <palves@redhat.com>
Thu, 1 Jan 2009 22:02:03 +0000 (22:02 +0000)
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.

gdb/ChangeLog
gdb/breakpoint.c
gdb/corefile.c
gdb/exceptions.h
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.base/watchpoint.exp

index a9f0b10..edce418 100644 (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:
index 30c89bd..83118bc 100644 (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;
index af2d1a3..c477660 100644 (file)
@@ -205,30 +205,22 @@ Use the \"file\" or \"exec-file\" command."));
 }
 \f
 
-/* 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.  */
index b6d4e12..6616dbf 100644 (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
 };
index 7244a1d..3b9c4b4 100644 (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
index 9935ef8..6557cba 100644 (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" {