* linux-low.c (linux_wait_1): Avoid setting need_step_over is

there's a GDB breakpoint at stop_pc.  Always report a trap to GDB
	if we could tell there's a GDB breakpoint at stop_pc.
	(need_step_over_p): Don't do a step over if we find a GDB
	breakpoint at the resume PC.

	* mem-break.c (struct raw_breakpoint): New.
	(enum bkpt_type): New type `gdb_breakpoint'.
	(struct breakpoint): Delete the `PC', `old_data' and `inserted'
	fields.  New field `raw'.
	(find_raw_breakpoint_at): New.
	(set_raw_breakpoint_at): Handle refcounting.  Create a raw
	breakpoint instead.
	(set_breakpoint_at): Adjust.
	(delete_raw_breakpoint): New.
	(release_breakpoint): New.
	(delete_breakpoint): Rename to...
	(delete_breakpoint_1): ... this.  Add proc parameter.  Use
	release_breakpoint.  Return ENOENT.
	(delete_breakpoint): Reimplement.
	(find_breakpoint_at): Delete.
	(find_gdb_breakpoint_at): New.
	(delete_breakpoint_at): Delete.
	(set_gdb_breakpoint_at): New.
	(delete_gdb_breakpoint_at): New.
	(gdb_breakpoint_here): New.
	(set_reinsert_breakpoint): Use release_breakpoint.
	(uninsert_breakpoint): Rename to ...
	(uninsert_raw_breakpoint): ... this.
	(uninsert_breakpoints_at): Adjust to handle raw breakpoints.
	(reinsert_raw_breakpoint): Change parameter type to
	raw_breakpoint.
	(reinsert_breakpoints_at): Adjust to handle raw breakpoints
	instead.
	(check_breakpoints): Adjust.  Use release_breakpoint.
	(breakpoint_here): Rewrite using find_raw_breakpoint_at.
	(breakpoint_inserted_here): Ditto.
	(check_mem_read): Adjust to iterate over raw breakpoints instead.
	Don't trust the breakpoint's shadow if it is not inserted.
	(check_mem_write): Adjust to iterate over raw breakpoints instead.
	(delete_all_breakpoints): Adjust.
	(free_all_breakpoints): Mark all breakpoints as uninserted, and
	use delete_breakpoint_1.

	* mem-break.h (breakpoints_supported): Delete declaration.
	(set_gdb_breakpoint_at): Declare.
	(gdb_breakpoint_here): Declare.
	(delete_breakpoint_at): Delete.
	(delete_gdb_breakpoint_at): Declare.

	* server.h (struct raw_breakpoint): Forward declare.
	(struct process_info): New field `raw_breakpoints'.

	* linux-x86-low.c (x86_insert_point, x86_remote_point): Handle Z0
	breakpoints.
This commit is contained in:
Pedro Alves 2010-04-01 14:25:34 +00:00
parent 86b17b608f
commit 8b07ae33f0
6 changed files with 362 additions and 95 deletions

View File

@ -1,3 +1,61 @@
2010-04-01 Pedro Alves <pedro@codesourcery.com>
* linux-low.c (linux_wait_1): Avoid setting need_step_over is
there's a GDB breakpoint at stop_pc. Always report a trap to GDB
if we could tell there's a GDB breakpoint at stop_pc.
(need_step_over_p): Don't do a step over if we find a GDB
breakpoint at the resume PC.
* mem-break.c (struct raw_breakpoint): New.
(enum bkpt_type): New type `gdb_breakpoint'.
(struct breakpoint): Delete the `PC', `old_data' and `inserted'
fields. New field `raw'.
(find_raw_breakpoint_at): New.
(set_raw_breakpoint_at): Handle refcounting. Create a raw
breakpoint instead.
(set_breakpoint_at): Adjust.
(delete_raw_breakpoint): New.
(release_breakpoint): New.
(delete_breakpoint): Rename to...
(delete_breakpoint_1): ... this. Add proc parameter. Use
release_breakpoint. Return ENOENT.
(delete_breakpoint): Reimplement.
(find_breakpoint_at): Delete.
(find_gdb_breakpoint_at): New.
(delete_breakpoint_at): Delete.
(set_gdb_breakpoint_at): New.
(delete_gdb_breakpoint_at): New.
(gdb_breakpoint_here): New.
(set_reinsert_breakpoint): Use release_breakpoint.
(uninsert_breakpoint): Rename to ...
(uninsert_raw_breakpoint): ... this.
(uninsert_breakpoints_at): Adjust to handle raw breakpoints.
(reinsert_raw_breakpoint): Change parameter type to
raw_breakpoint.
(reinsert_breakpoints_at): Adjust to handle raw breakpoints
instead.
(check_breakpoints): Adjust. Use release_breakpoint.
(breakpoint_here): Rewrite using find_raw_breakpoint_at.
(breakpoint_inserted_here): Ditto.
(check_mem_read): Adjust to iterate over raw breakpoints instead.
Don't trust the breakpoint's shadow if it is not inserted.
(check_mem_write): Adjust to iterate over raw breakpoints instead.
(delete_all_breakpoints): Adjust.
(free_all_breakpoints): Mark all breakpoints as uninserted, and
use delete_breakpoint_1.
* mem-break.h (breakpoints_supported): Delete declaration.
(set_gdb_breakpoint_at): Declare.
(gdb_breakpoint_here): Declare.
(delete_breakpoint_at): Delete.
(delete_gdb_breakpoint_at): Declare.
* server.h (struct raw_breakpoint): Forward declare.
(struct process_info): New field `raw_breakpoints'.
* linux-x86-low.c (x86_insert_point, x86_remote_point): Handle Z0
breakpoints.
2010-03-24 Pedro Alves <pedro@codesourcery.com>
* linux-low.c (status_pending_p_callback): Fix comment.

View File

@ -1740,7 +1740,8 @@ retry:
if (debug_threads)
fprintf (stderr, "Hit a gdbserver breakpoint.\n");
event_child->need_step_over = 1;
if (breakpoint_here (event_child->stop_pc))
event_child->need_step_over = 1;
}
}
else
@ -1755,11 +1756,18 @@ retry:
/* Check If GDB would be interested in this event. If GDB wanted
this thread to single step, we always want to report the SIGTRAP,
and let GDB handle it. */
and let GDB handle it. Watchpoints should always be reported.
So should signals we can't explain. A SIGTRAP we can't explain
could be a GDB breakpoint --- we may or not support Z0
breakpoints. If we do, we're be able to handle GDB breakpoints
on top of internal breakpoints, by handling the internal
breakpoint and still reporting the event to GDB. If we don't,
we're out of luck, GDB won't see the breakpoint hit. */
report_to_gdb = (!maybe_internal_trap
|| event_child->last_resume_kind == resume_step
|| event_child->stopped_by_watchpoint
|| (!step_over_finished && !bp_explains_trap));
|| (!step_over_finished && !bp_explains_trap)
|| gdb_breakpoint_here (event_child->stop_pc));
/* We found no reason GDB would want us to stop. We either hit one
of our own breakpoints, or finished an internal step GDB
@ -1801,6 +1809,8 @@ retry:
fprintf (stderr, "GDB wanted to single-step, reporting event.\n");
if (event_child->stopped_by_watchpoint)
fprintf (stderr, "Stopped by watchpoint.\n");
if (gdb_breakpoint_here (event_child->stop_pc))
fprintf (stderr, "Stopped by GDB breakpoint.\n");
if (debug_threads)
fprintf (stderr, "Hit a non-gdbserver trap event.\n");
}
@ -2401,21 +2411,37 @@ need_step_over_p (struct inferior_list_entry *entry, void *dummy)
saved_inferior = current_inferior;
current_inferior = get_lwp_thread (lwp);
/* We only step over our breakpoints. */
/* We can only step over breakpoints we know about. */
if (breakpoint_here (pc))
{
if (debug_threads)
fprintf (stderr,
"Need step over [LWP %ld]? yes, found breakpoint at 0x%s\n",
lwpid_of (lwp), paddress (pc));
/* Don't step over a breakpoint that GDB expects to hit
though. */
if (gdb_breakpoint_here (pc))
{
if (debug_threads)
fprintf (stderr,
"Need step over [LWP %ld]? yes, but found"
" GDB breakpoint at 0x%s; skipping step over\n",
lwpid_of (lwp), paddress (pc));
/* We've found an lwp that needs stepping over --- return 1 so
that find_inferior stops looking. */
current_inferior = saved_inferior;
current_inferior = saved_inferior;
return 0;
}
else
{
if (debug_threads)
fprintf (stderr,
"Need step over [LWP %ld]? yes, found breakpoint at 0x%s\n",
lwpid_of (lwp), paddress (pc));
/* If the step over is cancelled, this is set again. */
lwp->need_step_over = 0;
return 1;
/* We've found an lwp that needs stepping over --- return 1 so
that find_inferior stops looking. */
current_inferior = saved_inferior;
/* If the step over is cancelled, this is set again. */
lwp->need_step_over = 0;
return 1;
}
}
current_inferior = saved_inferior;

View File

@ -431,6 +431,8 @@ x86_insert_point (char type, CORE_ADDR addr, int len)
struct process_info *proc = current_process ();
switch (type)
{
case '0':
return set_gdb_breakpoint_at (addr);
case '2':
case '3':
case '4':
@ -448,6 +450,8 @@ x86_remove_point (char type, CORE_ADDR addr, int len)
struct process_info *proc = current_process ();
switch (type)
{
case '0':
return delete_gdb_breakpoint_at (addr);
case '2':
case '3':
case '4':

View File

@ -26,9 +26,53 @@ int breakpoint_len;
#define MAX_BREAKPOINT_LEN 8
/* GDB will never try to install multiple breakpoints at the same
address. But, we need to keep track of internal breakpoints too,
and so we do need to be able to install multiple breakpoints at the
same address transparently. We keep track of two different, and
closely related structures. A raw breakpoint, which manages the
low level, close to the metal aspect of a breakpoint. It holds the
breakpoint address, and a buffer holding a copy of the instructions
that would be in memory had not been a breakpoint there (we call
that the shadow memory of the breakpoint). We occasionally need to
temporarilly uninsert a breakpoint without the client knowing about
it (e.g., to step over an internal breakpoint), so we keep an
`inserted' state associated with this low level breakpoint
structure. There can only be one such object for a given address.
Then, we have (a bit higher level) breakpoints. This structure
holds a callback to be called whenever a breakpoint is hit, a
high-level type, and a link to a low level raw breakpoint. There
can be many high-level breakpoints at the same address, and all of
them will point to the same raw breakpoint, which is reference
counted. */
/* The low level, physical, raw breakpoint. */
struct raw_breakpoint
{
struct raw_breakpoint *next;
/* A reference count. Each high level breakpoint referencing this
raw breakpoint accounts for one reference. */
int refcount;
/* The breakpoint's insertion address. There can only be one raw
breakpoint for a given PC. */
CORE_ADDR pc;
/* The breakpoint's shadow memory. */
unsigned char old_data[MAX_BREAKPOINT_LEN];
/* Non-zero if this breakpoint is currently inserted in the
inferior. */
int inserted;
};
/* The type of a breakpoint. */
enum bkpt_type
{
/* A GDB breakpoint, requested with a Z0 packet. */
gdb_breakpoint,
/* A basic-software-single-step breakpoint. */
reinsert_breakpoint,
@ -37,38 +81,57 @@ enum bkpt_type
other_breakpoint,
};
/* A high level (in gdbserver's perspective) breakpoint. */
struct breakpoint
{
struct breakpoint *next;
CORE_ADDR pc;
unsigned char old_data[MAX_BREAKPOINT_LEN];
/* Non-zero if this breakpoint is currently inserted in the
inferior. */
int inserted;
/* The breakpoint's type. */
enum bkpt_type type;
/* Link to this breakpoint's raw breakpoint. This is always
non-NULL. */
struct raw_breakpoint *raw;
/* Function to call when we hit this breakpoint. If it returns 1,
the breakpoint shall be deleted; 0, it will be left inserted. */
the breakpoint shall be deleted; 0 or if this callback is NULL,
it will be left inserted. */
int (*handler) (CORE_ADDR);
};
static void uninsert_breakpoint (struct breakpoint *bp);
static struct raw_breakpoint *
find_raw_breakpoint_at (CORE_ADDR where)
{
struct process_info *proc = current_process ();
struct raw_breakpoint *bp;
static struct breakpoint *
for (bp = proc->raw_breakpoints; bp != NULL; bp = bp->next)
if (bp->pc == where)
return bp;
return NULL;
}
static struct raw_breakpoint *
set_raw_breakpoint_at (CORE_ADDR where)
{
struct process_info *proc = current_process ();
struct breakpoint *bp;
struct raw_breakpoint *bp;
int err;
if (breakpoint_data == NULL)
error ("Target does not support breakpoints.");
bp = find_raw_breakpoint_at (where);
if (bp != NULL)
{
bp->refcount++;
return bp;
}
bp = xcalloc (1, sizeof (*bp));
bp->pc = where;
bp->refcount = 1;
err = (*the_target->read_memory) (where, bp->old_data,
breakpoint_len);
@ -97,8 +160,8 @@ set_raw_breakpoint_at (CORE_ADDR where)
/* Link the breakpoint in. */
bp->inserted = 1;
bp->next = proc->breakpoints;
proc->breakpoints = bp;
bp->next = proc->raw_breakpoints;
proc->raw_breakpoints = bp;
return bp;
}
@ -107,10 +170,11 @@ set_breakpoint_at (CORE_ADDR where, int (*handler) (CORE_ADDR))
{
struct process_info *proc = current_process ();
struct breakpoint *bp;
struct raw_breakpoint *raw;
bp = set_raw_breakpoint_at (where);
raw = set_raw_breakpoint_at (where);
if (bp == NULL)
if (raw == NULL)
{
/* warn? */
return NULL;
@ -118,6 +182,8 @@ set_breakpoint_at (CORE_ADDR where, int (*handler) (CORE_ADDR))
bp = xcalloc (1, sizeof (struct breakpoint));
bp->type = other_breakpoint;
bp->raw = raw;
bp->handler = handler;
bp->next = proc->breakpoints;
@ -126,11 +192,84 @@ set_breakpoint_at (CORE_ADDR where, int (*handler) (CORE_ADDR))
return bp;
}
static void
delete_breakpoint (struct breakpoint *todel)
static int
delete_raw_breakpoint (struct process_info *proc, struct raw_breakpoint *todel)
{
struct raw_breakpoint *bp, **bp_link;
int ret;
bp = proc->raw_breakpoints;
bp_link = &proc->raw_breakpoints;
while (bp)
{
if (bp == todel)
{
if (bp->inserted)
{
struct raw_breakpoint *prev_bp_link = *bp_link;
*bp_link = bp->next;
ret = (*the_target->write_memory) (bp->pc, bp->old_data,
breakpoint_len);
if (ret != 0)
{
/* Something went wrong, relink the breakpoint. */
*bp_link = prev_bp_link;
if (debug_threads)
fprintf (stderr,
"Failed to uninsert raw breakpoint "
"at 0x%s (%s) while deleting it.\n",
paddress (bp->pc), strerror (ret));
return ret;
}
}
else
*bp_link = bp->next;
free (bp);
return 0;
}
else
{
bp_link = &bp->next;
bp = *bp_link;
}
}
warning ("Could not find raw breakpoint in list.");
return ENOENT;
}
static int
release_breakpoint (struct process_info *proc, struct breakpoint *bp)
{
int newrefcount;
int ret;
newrefcount = bp->raw->refcount - 1;
if (newrefcount == 0)
{
ret = delete_raw_breakpoint (proc, bp->raw);
if (ret != 0)
return ret;
}
else
bp->raw->refcount = newrefcount;
free (bp);
return 0;
}
static int
delete_breakpoint_1 (struct process_info *proc, struct breakpoint *todel)
{
struct process_info *proc = current_process ();
struct breakpoint *bp, **bp_link;
int err;
bp = proc->breakpoints;
bp_link = &proc->breakpoints;
@ -141,9 +280,12 @@ delete_breakpoint (struct breakpoint *todel)
{
*bp_link = bp->next;
uninsert_breakpoint (bp);
free (bp);
return;
err = release_breakpoint (proc, bp);
if (err != 0)
return err;
bp = *bp_link;
return 0;
}
else
{
@ -153,30 +295,71 @@ delete_breakpoint (struct breakpoint *todel)
}
warning ("Could not find breakpoint in list.");
return ENOENT;
}
static int
delete_breakpoint (struct breakpoint *todel)
{
struct process_info *proc = current_process ();
return delete_breakpoint_1 (proc, todel);
}
static struct breakpoint *
find_breakpoint_at (CORE_ADDR where)
find_gdb_breakpoint_at (CORE_ADDR where)
{
struct process_info *proc = current_process ();
struct breakpoint *bp = proc->breakpoints;
struct breakpoint *bp;
while (bp != NULL)
{
if (bp->pc == where)
return bp;
bp = bp->next;
}
for (bp = proc->breakpoints; bp != NULL; bp = bp->next)
if (bp->type == gdb_breakpoint && bp->raw->pc == where)
return bp;
return NULL;
}
void
delete_breakpoint_at (CORE_ADDR addr)
int
set_gdb_breakpoint_at (CORE_ADDR where)
{
struct breakpoint *bp = find_breakpoint_at (addr);
if (bp != NULL)
delete_breakpoint (bp);
struct breakpoint *bp;
if (breakpoint_data == NULL)
return 1;
bp = set_breakpoint_at (where, NULL);
if (bp == NULL)
return -1;
bp->type = gdb_breakpoint;
return 0;
}
int
delete_gdb_breakpoint_at (CORE_ADDR addr)
{
struct breakpoint *bp;
int err;
if (breakpoint_data == NULL)
return 1;
bp = find_gdb_breakpoint_at (addr);
if (bp == NULL)
return -1;
err = delete_breakpoint (bp);
if (err)
return -1;
return 0;
}
int
gdb_breakpoint_here (CORE_ADDR where)
{
struct breakpoint *bp = find_gdb_breakpoint_at (where);
return (bp != NULL);
}
void
@ -185,7 +368,6 @@ set_reinsert_breakpoint (CORE_ADDR stop_at)
struct breakpoint *bp;
bp = set_breakpoint_at (stop_at, NULL);
bp->type = reinsert_breakpoint;
}
@ -203,13 +385,7 @@ delete_reinsert_breakpoints (void)
if (bp->type == reinsert_breakpoint)
{
*bp_link = bp->next;
/* If something goes wrong, maybe this is a shared library
breakpoint, and the shared library has been unmapped.
Assume the breakpoint is gone anyway. */
uninsert_breakpoint (bp);
free (bp);
release_breakpoint (proc, bp);
bp = *bp_link;
}
else
@ -221,7 +397,7 @@ delete_reinsert_breakpoints (void)
}
static void
uninsert_breakpoint (struct breakpoint *bp)
uninsert_raw_breakpoint (struct raw_breakpoint *bp)
{
if (bp->inserted)
{
@ -245,9 +421,9 @@ uninsert_breakpoint (struct breakpoint *bp)
void
uninsert_breakpoints_at (CORE_ADDR pc)
{
struct breakpoint *bp;
struct raw_breakpoint *bp;
bp = find_breakpoint_at (pc);
bp = find_raw_breakpoint_at (pc);
if (bp == NULL)
{
/* This can happen when we remove all breakpoints while handling
@ -261,11 +437,11 @@ uninsert_breakpoints_at (CORE_ADDR pc)
}
if (bp->inserted)
uninsert_breakpoint (bp);
uninsert_raw_breakpoint (bp);
}
static void
reinsert_raw_breakpoint (struct breakpoint *bp)
reinsert_raw_breakpoint (struct raw_breakpoint *bp)
{
int err;
@ -285,16 +461,16 @@ reinsert_raw_breakpoint (struct breakpoint *bp)
void
reinsert_breakpoints_at (CORE_ADDR pc)
{
struct breakpoint *bp;
struct raw_breakpoint *bp;
bp = find_breakpoint_at (pc);
bp = find_raw_breakpoint_at (pc);
if (bp == NULL)
{
/* This can happen when we remove all breakpoints while handling
a step-over. */
if (debug_threads)
fprintf (stderr,
"Could not find breakpoint at 0x%s "
"Could not find raw breakpoint at 0x%s "
"in list (reinserting).\n",
paddress (pc));
return;
@ -314,9 +490,9 @@ check_breakpoints (CORE_ADDR stop_pc)
while (bp)
{
if (bp->pc == stop_pc)
if (bp->raw->pc == stop_pc)
{
if (!bp->inserted)
if (!bp->raw->inserted)
{
warning ("Hit a removed breakpoint?");
return;
@ -326,7 +502,7 @@ check_breakpoints (CORE_ADDR stop_pc)
{
*bp_link = bp->next;
delete_breakpoint (bp);
release_breakpoint (proc, bp);
bp = *bp_link;
continue;
@ -348,34 +524,24 @@ set_breakpoint_data (const unsigned char *bp_data, int bp_len)
int
breakpoint_here (CORE_ADDR addr)
{
struct process_info *proc = current_process ();
struct breakpoint *bp;
for (bp = proc->breakpoints; bp != NULL; bp = bp->next)
if (bp->pc == addr)
return 1;
return 0;
return (find_raw_breakpoint_at (addr) != NULL);
}
int
breakpoint_inserted_here (CORE_ADDR addr)
{
struct process_info *proc = current_process ();
struct breakpoint *bp;
struct raw_breakpoint *bp;
for (bp = proc->breakpoints; bp != NULL; bp = bp->next)
if (bp->pc == addr && bp->inserted)
return 1;
bp = find_raw_breakpoint_at (addr);
return 0;
return (bp != NULL && bp->inserted);
}
void
check_mem_read (CORE_ADDR mem_addr, unsigned char *buf, int mem_len)
{
struct process_info *proc = current_process ();
struct breakpoint *bp = proc->breakpoints;
struct raw_breakpoint *bp = proc->raw_breakpoints;
CORE_ADDR mem_end = mem_addr + mem_len;
for (; bp != NULL; bp = bp->next)
@ -401,7 +567,8 @@ check_mem_read (CORE_ADDR mem_addr, unsigned char *buf, int mem_len)
copy_offset = start - bp->pc;
buf_offset = start - mem_addr;
memcpy (buf + buf_offset, bp->old_data + copy_offset, copy_len);
if (bp->inserted)
memcpy (buf + buf_offset, bp->old_data + copy_offset, copy_len);
}
}
@ -409,7 +576,7 @@ void
check_mem_write (CORE_ADDR mem_addr, unsigned char *buf, int mem_len)
{
struct process_info *proc = current_process ();
struct breakpoint *bp = proc->breakpoints;
struct raw_breakpoint *bp = proc->raw_breakpoints;
CORE_ADDR mem_end = mem_addr + mem_len;
for (; bp != NULL; bp = bp->next)
@ -449,7 +616,7 @@ delete_all_breakpoints (void)
struct process_info *proc = current_process ();
while (proc->breakpoints)
delete_breakpoint (proc->breakpoints);
delete_breakpoint_1 (proc, proc->breakpoints);
}
/* Release all breakpoints, but do not try to un-insert them from the
@ -458,12 +625,15 @@ delete_all_breakpoints (void)
void
free_all_breakpoints (struct process_info *proc)
{
struct breakpoint *bp;
struct raw_breakpoint *raw_bp;
for (raw_bp = proc->raw_breakpoints; raw_bp != NULL; raw_bp = raw_bp->next)
raw_bp->inserted = 0;
/* Note: use PROC explicitly instead of deferring to
delete_all_breakpoints --- CURRENT_INFERIOR may already have been
released when we get here. There should be no call to
current_process from here on. */
while (proc->breakpoints)
{
bp = proc->breakpoints;
proc->breakpoints = bp->next;
free (bp);
}
delete_breakpoint_1 (proc, proc->breakpoints);
}

View File

@ -25,9 +25,10 @@
/* Breakpoints are opaque. */
struct breakpoint;
/* Returns TRUE if breakpoints are supported on this target. */
/* Create a new GDB breakpoint at WHERE. Returns -1 if breakpoints
are not supported on this target, 0 otherwise. */
int breakpoints_supported (void);
int set_gdb_breakpoint_at (CORE_ADDR where);
/* Returns TRUE if there's any breakpoint at ADDR in our tables,
inserted, or not. */
@ -38,6 +39,10 @@ int breakpoint_here (CORE_ADDR addr);
int breakpoint_inserted_here (CORE_ADDR addr);
/* Returns TRUE if there's a GDB breakpoint set at ADDR. */
int gdb_breakpoint_here (CORE_ADDR where);
/* Create a new breakpoint at WHERE, and call HANDLER when
it is hit. HANDLER should return 1 if the breakpoint
should be deleted, 0 otherwise. */
@ -45,10 +50,10 @@ int breakpoint_inserted_here (CORE_ADDR addr);
struct breakpoint *set_breakpoint_at (CORE_ADDR where,
int (*handler) (CORE_ADDR));
/* Delete a breakpoint previously inserted at ADDR with
set_breakpoint_at. */
/* Delete a GDB breakpoint previously inserted at ADDR with
set_gdb_breakpoint_at. */
void delete_breakpoint_at (CORE_ADDR addr);
int delete_gdb_breakpoint_at (CORE_ADDR addr);
/* Set a reinsert breakpoint at STOP_AT. */

View File

@ -191,6 +191,7 @@ struct dll_info
struct sym_cache;
struct breakpoint;
struct raw_breakpoint;
struct process_info_private;
struct process_info
@ -209,6 +210,9 @@ struct process_info
/* The list of memory breakpoints. */
struct breakpoint *breakpoints;
/* The list of raw memory breakpoints. */
struct raw_breakpoint *raw_breakpoints;
/* Private target data. */
struct process_info_private *private;
};