aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog16
-rw-r--r--gdb/breakpoint.c105
-rw-r--r--gdb/exceptions.h3
-rw-r--r--gdb/remote.c6
-rw-r--r--gdb/target.h11
5 files changed, 111 insertions, 30 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 315da65..850709b 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,19 @@
+2014-01-09 Pedro Alves <palves@redhat.com>
+ Hui Zhu <hui@codesourcery.com>
+
+ PR gdb/16101
+ * breakpoint.c (insert_bp_location): Rename hw_bp_err_string to
+ bp_err_string. Don't mark the location shlib_disabled if the
+ error thrown wasn't a generic or memory error. Catch errors
+ thrown while inserting breakpoints in overlayed code. Output
+ error message of software breakpoints.
+ * remote.c (remote_insert_breakpoint): If this breakpoint has
+ target-side commands but this stub doesn't support Z0 packets,
+ throw NOT_SUPPORTED_ERROR error.
+ * exceptions.h (enum errors) <NOT_SUPPORTED_ERROR>: New error.
+ * target.h (target_insert_breakpoint): Extend comment.
+ (target_insert_hw_breakpoint): Add comment.
+
2014-01-08 Pedro Alves <palves@redhat.com>
* remote.c (remote_add_thread): Add threads silently if starting
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 66a69b5..152f638 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -2394,8 +2394,8 @@ insert_bp_location (struct bp_location *bl,
int *hw_breakpoint_error,
int *hw_bp_error_explained_already)
{
- int val = 0;
- const char *hw_bp_err_string = NULL;
+ enum errors bp_err = GDB_NO_ERROR;
+ const char *bp_err_message = NULL;
struct gdb_exception e;
if (!should_be_inserted (bl) || (bl->inserted && !bl->needs_update))
@@ -2495,12 +2495,16 @@ insert_bp_location (struct bp_location *bl,
/* No overlay handling: just set the breakpoint. */
TRY_CATCH (e, RETURN_MASK_ALL)
{
+ int val;
+
val = bl->owner->ops->insert_location (bl);
+ if (val)
+ bp_err = GENERIC_ERROR;
}
if (e.reason < 0)
{
- val = 1;
- hw_bp_err_string = e.message;
+ bp_err = e.error;
+ bp_err_message = e.message;
}
}
else
@@ -2522,9 +2526,24 @@ insert_bp_location (struct bp_location *bl,
/* Set a software (trap) breakpoint at the LMA. */
bl->overlay_target_info = bl->target_info;
bl->overlay_target_info.placed_address = addr;
- val = target_insert_breakpoint (bl->gdbarch,
- &bl->overlay_target_info);
- if (val != 0)
+
+ /* No overlay handling: just set the breakpoint. */
+ TRY_CATCH (e, RETURN_MASK_ALL)
+ {
+ int val;
+
+ val = target_insert_breakpoint (bl->gdbarch,
+ &bl->overlay_target_info);
+ if (val)
+ bp_err = GENERIC_ERROR;
+ }
+ if (e.reason < 0)
+ {
+ bp_err = e.error;
+ bp_err_message = e.message;
+ }
+
+ if (bp_err != GDB_NO_ERROR)
fprintf_unfiltered (tmp_error_stream,
"Overlay breakpoint %d "
"failed: in ROM?\n",
@@ -2537,12 +2556,16 @@ insert_bp_location (struct bp_location *bl,
/* Yes. This overlay section is mapped into memory. */
TRY_CATCH (e, RETURN_MASK_ALL)
{
+ int val;
+
val = bl->owner->ops->insert_location (bl);
+ if (val)
+ bp_err = GENERIC_ERROR;
}
if (e.reason < 0)
{
- val = 1;
- hw_bp_err_string = e.message;
+ bp_err = e.error;
+ bp_err_message = e.message;
}
}
else
@@ -2553,13 +2576,23 @@ insert_bp_location (struct bp_location *bl,
}
}
- if (val)
+ if (bp_err != GDB_NO_ERROR)
{
/* Can't set the breakpoint. */
- if (solib_name_from_address (bl->pspace, bl->address))
+
+ /* In some cases, we might not be able to insert a
+ breakpoint in a shared library that has already been
+ removed, but we have not yet processed the shlib unload
+ event. Unfortunately, some targets that implement
+ breakpoint insertion themselves (necessary if this is a
+ HW breakpoint, but SW breakpoints likewise) can't tell
+ why the breakpoint insertion failed (e.g., the remote
+ target doesn't define error codes), so we must treat
+ generic errors as memory errors. */
+ if ((bp_err == GENERIC_ERROR || bp_err == MEMORY_ERROR)
+ && solib_name_from_address (bl->pspace, bl->address))
{
/* See also: disable_breakpoints_in_shlibs. */
- val = 0;
bl->shlib_disabled = 1;
observer_notify_breakpoint_modified (bl->owner);
if (!*disabled_breaks)
@@ -2574,39 +2607,51 @@ insert_bp_location (struct bp_location *bl,
*disabled_breaks = 1;
fprintf_unfiltered (tmp_error_stream,
"breakpoint #%d\n", bl->owner->number);
+ return 0;
}
else
{
if (bl->loc_type == bp_loc_hardware_breakpoint)
{
- *hw_breakpoint_error = 1;
- *hw_bp_error_explained_already = hw_bp_err_string != NULL;
+ *hw_breakpoint_error = 1;
+ *hw_bp_error_explained_already = bp_err_message != NULL;
fprintf_unfiltered (tmp_error_stream,
"Cannot insert hardware breakpoint %d%s",
- bl->owner->number, hw_bp_err_string ? ":" : ".\n");
- if (hw_bp_err_string)
- fprintf_unfiltered (tmp_error_stream, "%s.\n", hw_bp_err_string);
+ bl->owner->number, bp_err_message ? ":" : ".\n");
+ if (bp_err_message != NULL)
+ fprintf_unfiltered (tmp_error_stream, "%s.\n", bp_err_message);
}
else
{
- char *message = memory_error_message (TARGET_XFER_E_IO,
- bl->gdbarch, bl->address);
- struct cleanup *old_chain = make_cleanup (xfree, message);
-
- fprintf_unfiltered (tmp_error_stream,
- "Cannot insert breakpoint %d.\n"
- "%s\n",
- bl->owner->number, message);
-
- do_cleanups (old_chain);
+ if (bp_err_message == NULL)
+ {
+ char *message
+ = memory_error_message (TARGET_XFER_E_IO,
+ bl->gdbarch, bl->address);
+ struct cleanup *old_chain = make_cleanup (xfree, message);
+
+ fprintf_unfiltered (tmp_error_stream,
+ "Cannot insert breakpoint %d.\n"
+ "%s\n",
+ bl->owner->number, message);
+ do_cleanups (old_chain);
+ }
+ else
+ {
+ fprintf_unfiltered (tmp_error_stream,
+ "Cannot insert breakpoint %d: %s\n",
+ bl->owner->number,
+ bp_err_message);
+ }
}
+ return 1;
}
}
else
bl->inserted = 1;
- return val;
+ return 0;
}
else if (bl->loc_type == bp_loc_hardware_watchpoint
@@ -2614,6 +2659,8 @@ insert_bp_location (struct bp_location *bl,
watchpoints. It's not clear that it's necessary... */
&& bl->owner->disposition != disp_del_at_next_stop)
{
+ int val;
+
gdb_assert (bl->owner->ops != NULL
&& bl->owner->ops->insert_location != NULL);
@@ -2657,6 +2704,8 @@ insert_bp_location (struct bp_location *bl,
else if (bl->owner->type == bp_catchpoint)
{
+ int val;
+
gdb_assert (bl->owner->ops != NULL
&& bl->owner->ops->insert_location != NULL);
diff --git a/gdb/exceptions.h b/gdb/exceptions.h
index 1eaafca..b8dadc7 100644
--- a/gdb/exceptions.h
+++ b/gdb/exceptions.h
@@ -97,6 +97,9 @@ enum errors {
/* An undefined command was executed. */
UNDEFINED_COMMAND_ERROR,
+ /* Requested feature, method, mechanism, etc. is not supported. */
+ NOT_SUPPORTED_ERROR,
+
/* Add more errors here. */
NR_ERRORS
};
diff --git a/gdb/remote.c b/gdb/remote.c
index 70946b1..17edbd2 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -8313,6 +8313,12 @@ remote_insert_breakpoint (struct gdbarch *gdbarch,
}
}
+ /* If this breakpoint has target-side commands but this stub doesn't
+ support Z0 packets, throw error. */
+ if (!VEC_empty (agent_expr_p, bp_tgt->tcommands))
+ throw_error (NOT_SUPPORTED_ERROR, _("\
+Target doesn't support breakpoints that have target side commands."));
+
return memory_insert_breakpoint (gdbarch, bp_tgt);
}
diff --git a/gdb/target.h b/gdb/target.h
index 4b52fb6..ab985e4 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -1127,8 +1127,10 @@ int target_write_memory_blocks (VEC(memory_write_request_s) *requests,
#define target_files_info() \
(*current_target.to_files_info) (&current_target)
-/* Insert a breakpoint at address BP_TGT->placed_address in the target
- machine. Result is 0 for success, non-zero for error. */
+/* Insert a hardware breakpoint at address BP_TGT->placed_address in
+ the target machine. Returns 0 for success, and returns non-zero or
+ throws an error (with a detailed failure reason error code and
+ message) otherwise. */
extern int target_insert_breakpoint (struct gdbarch *gdbarch,
struct bp_target_info *bp_tgt);
@@ -1557,6 +1559,11 @@ extern int target_insert_mask_watchpoint (CORE_ADDR, CORE_ADDR, int);
extern int target_remove_mask_watchpoint (CORE_ADDR, CORE_ADDR, int);
+/* Insert a hardware breakpoint at address BP_TGT->placed_address in
+ the target machine. Returns 0 for success, and returns non-zero or
+ throws an error (with a detailed failure reason error code and
+ message) otherwise. */
+
#define target_insert_hw_breakpoint(gdbarch, bp_tgt) \
(*current_target.to_insert_hw_breakpoint) (gdbarch, bp_tgt)