* 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

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