{
struct process_info *proc = current_process ();
struct raw_breakpoint *bp;
+ struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
if (type == raw_bkpt_type_sw || type == raw_bkpt_type_hw)
{
else
bp = find_raw_breakpoint_at (where, type, kind);
- if (bp != NULL)
+ if (bp == NULL)
{
- bp->refcount++;
- return bp;
+ bp = XCNEW (struct raw_breakpoint);
+ bp->pc = where;
+ bp->kind = kind;
+ bp->raw_type = type;
+ make_cleanup (xfree, bp);
}
- bp = XCNEW (struct raw_breakpoint);
- bp->pc = where;
- bp->kind = kind;
- bp->refcount = 1;
- bp->raw_type = type;
-
- *err = the_target->insert_point (bp->raw_type, bp->pc, bp->kind, bp);
- if (*err != 0)
+ if (!bp->inserted)
{
- if (debug_threads)
- debug_printf ("Failed to insert breakpoint at 0x%s (%d).\n",
- paddress (where), *err);
- free (bp);
- return NULL;
+ *err = the_target->insert_point (bp->raw_type, bp->pc, bp->kind, bp);
+ if (*err != 0)
+ {
+ if (debug_threads)
+ debug_printf ("Failed to insert breakpoint at 0x%s (%d).\n",
+ paddress (where), *err);
+
+ do_cleanups (old_chain);
+ return NULL;
+ }
+
+ bp->inserted = 1;
}
- bp->inserted = 1;
- /* Link the breakpoint in. */
- bp->next = proc->raw_breakpoints;
- proc->raw_breakpoints = bp;
+ discard_cleanups (old_chain);
+
+ /* Link the breakpoint in, if this is the first reference. */
+ if (++bp->refcount == 1)
+ {
+ bp->next = proc->raw_breakpoints;
+ proc->raw_breakpoints = bp;
+ }
return bp;
}
uninsert_raw_breakpoint (bp);
}
+void
+uninsert_reinsert_breakpoints (void)
+{
+ struct process_info *proc = current_process ();
+ struct breakpoint *bp;
+
+ for (bp = proc->breakpoints; bp != NULL; bp = bp->next)
+ {
+ if (bp->type == reinsert_breakpoint)
+ {
+ gdb_assert (bp->raw->inserted > 0);
+
+ /* Only uninsert the raw breakpoint if it only belongs to a
+ reinsert breakpoint. */
+ if (bp->raw->refcount == 1)
+ uninsert_raw_breakpoint (bp->raw);
+ }
+ }
+}
+
static void
reinsert_raw_breakpoint (struct raw_breakpoint *bp)
{
int err;
if (bp->inserted)
- error ("Breakpoint already inserted at reinsert time.");
+ return;
err = the_target->insert_point (bp->raw_type, bp->pc, bp->kind, bp);
if (err == 0)
}
}
+int
+has_reinsert_breakpoints (struct process_info *proc)
+{
+ struct breakpoint *bp, **bp_link;
+
+ bp = proc->breakpoints;
+ bp_link = &proc->breakpoints;
+
+ while (bp)
+ {
+ if (bp->type == reinsert_breakpoint)
+ return 1;
+ else
+ {
+ bp_link = &bp->next;
+ bp = *bp_link;
+ }
+ }
+
+ return 0;
+}
+
void
reinsert_all_breakpoints (void)
{
reinsert_raw_breakpoint (bp);
}
+void
+reinsert_reinsert_breakpoints (void)
+{
+ struct process_info *proc = current_process ();
+ struct breakpoint *bp;
+
+ for (bp = proc->breakpoints; bp != NULL; bp = bp->next)
+ {
+ if (bp->type == reinsert_breakpoint)
+ {
+ gdb_assert (bp->raw->inserted > 0);
+
+ if (bp->raw->refcount == 1)
+ reinsert_raw_breakpoint (bp->raw);
+ }
+ }
+}
+
void
check_breakpoints (CORE_ADDR stop_pc)
{
{
next = bp->next;
if (bp->raw->inserted < 0)
- delete_breakpoint_1 (proc, bp);
+ {
+ /* If reinsert_breakpoints become disabled, that means the
+ manipulations (insertion and removal) of them are wrong. */
+ gdb_assert (bp->type != reinsert_breakpoint);
+ delete_breakpoint_1 (proc, bp);
+ }
}
}