mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-12-09 04:21:49 +08:00
* linux-low.c (linux_kill, linux_detach): Adjust.
(status_pending_p_callback): Remove redundant statement. Check for !TARGET_WAITIKIND_IGNORE, instead of TARGET_WAITKIND_STOPPED. (handle_tracepoints): Make sure LWP is locked. Adjust. (linux_wait_for_event_1): Adjust. (linux_cancel_breakpoints): New. (unsuspend_one_lwp): New. (unsuspend_all_lwps): New. (linux_wait_1): If finishing a step-over, unsuspend all lwps. (send_sigstop_callback): Change return type to int, add new `except' parameter and handle it. (suspend_and_send_sigstop_callback): New. (stop_all_lwps): Add new `suspend' and `expect' parameters, and pass them down. If SUSPEND, also increment the lwp's suspend count. (linux_resume_one_lwp): Add notice about resuming a suspended LWP. (need_step_over_p): Don't consider suspended LWPs. (start_step_over): Adjust. (proceed_one_lwp): Change return type to int, add new `except' parameter and handle it. (unsuspend_and_proceed_one_lwp): New. (proceed_all_lwps): Use find_inferior instead of for_each_inferior. (unstop_all_lwps): Add `unsuspend' parameter. If UNSUSPEND, them also decrement the suspend count of LWPs. Pass `except' down, instead of hacking its suspend count. (linux_pause_all): Add `freeze' parameter. Adjust. (linux_unpause_all): New. (linux_target_ops): Install linux_unpause_all. * server.c (handle_status): Adjust. * target.h (struct target_ops): New fields `unpause_all' and `cancel_breakpoints'. Add new parameter to `pause_all'. (pause_all): Add new `freeze' parameter. (unpause_all): New. (cancel_breakpoints): New. * tracepoint.c (clear_installed_tracepoints): Pause threads, and cancel breakpoints. (cmd_qtstart): Pause threads. (stop_tracing): Pause threads, and cancel breakpoints. * win32-low.c (win32_target_ops): Adjust.
This commit is contained in:
parent
e471f25b4b
commit
7984d53228
@ -1,3 +1,47 @@
|
||||
2010-05-03 Pedro Alves <pedro@codesourcery.com>
|
||||
|
||||
* linux-low.c (linux_kill, linux_detach): Adjust.
|
||||
(status_pending_p_callback): Remove redundant statement. Check
|
||||
for !TARGET_WAITIKIND_IGNORE, instead of
|
||||
TARGET_WAITKIND_STOPPED.
|
||||
(handle_tracepoints): Make sure LWP is locked. Adjust.
|
||||
(linux_wait_for_event_1): Adjust.
|
||||
(linux_cancel_breakpoints): New.
|
||||
(unsuspend_one_lwp): New.
|
||||
(unsuspend_all_lwps): New.
|
||||
(linux_wait_1): If finishing a step-over, unsuspend all lwps.
|
||||
(send_sigstop_callback): Change return type to int, add new
|
||||
`except' parameter and handle it.
|
||||
(suspend_and_send_sigstop_callback): New.
|
||||
(stop_all_lwps): Add new `suspend' and `expect' parameters, and
|
||||
pass them down. If SUSPEND, also increment the lwp's suspend
|
||||
count.
|
||||
(linux_resume_one_lwp): Add notice about resuming a suspended LWP.
|
||||
(need_step_over_p): Don't consider suspended LWPs.
|
||||
(start_step_over): Adjust.
|
||||
(proceed_one_lwp): Change return type to int, add new `except'
|
||||
parameter and handle it.
|
||||
(unsuspend_and_proceed_one_lwp): New.
|
||||
(proceed_all_lwps): Use find_inferior instead of
|
||||
for_each_inferior.
|
||||
(unstop_all_lwps): Add `unsuspend' parameter. If UNSUSPEND, them
|
||||
also decrement the suspend count of LWPs. Pass `except' down,
|
||||
instead of hacking its suspend count.
|
||||
(linux_pause_all): Add `freeze' parameter. Adjust.
|
||||
(linux_unpause_all): New.
|
||||
(linux_target_ops): Install linux_unpause_all.
|
||||
* server.c (handle_status): Adjust.
|
||||
* target.h (struct target_ops): New fields `unpause_all' and
|
||||
`cancel_breakpoints'. Add new parameter to `pause_all'.
|
||||
(pause_all): Add new `freeze' parameter.
|
||||
(unpause_all): New.
|
||||
(cancel_breakpoints): New.
|
||||
* tracepoint.c (clear_installed_tracepoints): Pause threads, and
|
||||
cancel breakpoints.
|
||||
(cmd_qtstart): Pause threads.
|
||||
(stop_tracing): Pause threads, and cancel breakpoints.
|
||||
* win32-low.c (win32_target_ops): Adjust.
|
||||
|
||||
2010-05-03 Pedro Alves <pedro@codesourcery.com>
|
||||
|
||||
* linux-low.c (linux_wait_for_event_1): Move passing the signal to
|
||||
|
@ -139,14 +139,14 @@ static int new_inferior;
|
||||
static void linux_resume_one_lwp (struct lwp_info *lwp,
|
||||
int step, int signal, siginfo_t *info);
|
||||
static void linux_resume (struct thread_resume *resume_info, size_t n);
|
||||
static void stop_all_lwps (void);
|
||||
static void stop_all_lwps (int suspend, struct lwp_info *except);
|
||||
static void unstop_all_lwps (int unsuspend, struct lwp_info *except);
|
||||
static int linux_wait_for_event (ptid_t ptid, int *wstat, int options);
|
||||
static void *add_lwp (ptid_t ptid);
|
||||
static int linux_stopped_by_watchpoint (void);
|
||||
static void mark_lwp_dead (struct lwp_info *lwp, int wstat);
|
||||
static int linux_core_of_thread (ptid_t ptid);
|
||||
static void proceed_all_lwps (void);
|
||||
static void unstop_all_lwps (struct lwp_info *except);
|
||||
static int finish_step_over (struct lwp_info *lwp);
|
||||
static CORE_ADDR get_stop_pc (struct lwp_info *lwp);
|
||||
static int kill_lwp (unsigned long lwpid, int signo);
|
||||
@ -765,7 +765,7 @@ linux_kill (int pid)
|
||||
|
||||
/* If we're killing a running inferior, make sure it is stopped
|
||||
first, as PTRACE_KILL will not work otherwise. */
|
||||
stop_all_lwps ();
|
||||
stop_all_lwps (0, NULL);
|
||||
|
||||
find_inferior (&all_threads, linux_kill_one_lwp, &pid);
|
||||
|
||||
@ -790,7 +790,7 @@ linux_kill (int pid)
|
||||
|
||||
/* Since we presently can only stop all lwps of all processes, we
|
||||
need to unstop lwps of other processes. */
|
||||
unstop_all_lwps (NULL);
|
||||
unstop_all_lwps (0, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -840,7 +840,7 @@ linux_detach (int pid)
|
||||
the thread is stopped to sucessfully detach. Second, thread_db
|
||||
may need to uninstall thread event breakpoints from memory, which
|
||||
only works with a stopped process anyway. */
|
||||
stop_all_lwps ();
|
||||
stop_all_lwps (0, NULL);
|
||||
|
||||
#ifdef USE_THREAD_DB
|
||||
thread_db_detach (process);
|
||||
@ -852,7 +852,7 @@ linux_detach (int pid)
|
||||
|
||||
/* Since we presently can only stop all lwps of all processes, we
|
||||
need to unstop lwps of other processes. */
|
||||
unstop_all_lwps (NULL);
|
||||
unstop_all_lwps (0, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -928,7 +928,7 @@ status_pending_p_callback (struct inferior_list_entry *entry, void *arg)
|
||||
{
|
||||
struct lwp_info *lwp = (struct lwp_info *) entry;
|
||||
ptid_t ptid = * (ptid_t *) arg;
|
||||
struct thread_info *thread = get_lwp_thread (lwp);
|
||||
struct thread_info *thread;
|
||||
|
||||
/* Check if we're only interested in events from a specific process
|
||||
or its lwps. */
|
||||
@ -941,7 +941,7 @@ status_pending_p_callback (struct inferior_list_entry *entry, void *arg)
|
||||
/* If we got a `vCont;t', but we haven't reported a stop yet, do
|
||||
report any status pending the LWP may have. */
|
||||
if (thread->last_resume_kind == resume_stop
|
||||
&& thread->last_status.kind == TARGET_WAITKIND_STOPPED)
|
||||
&& thread->last_status.kind != TARGET_WAITKIND_IGNORE)
|
||||
return 0;
|
||||
|
||||
return lwp->status_pending_p;
|
||||
@ -1113,6 +1113,12 @@ handle_tracepoints (struct lwp_info *lwp)
|
||||
struct thread_info *tinfo = get_lwp_thread (lwp);
|
||||
int tpoint_related_event = 0;
|
||||
|
||||
/* If this tracepoint hit causes a tracing stop, we'll immediately
|
||||
uninsert tracepoints. To do this, we temporarily pause all
|
||||
threads, unpatch away, and then unpause threads. We need to make
|
||||
sure the unpausing doesn't resume LWP too. */
|
||||
lwp->suspended++;
|
||||
|
||||
/* And we need to be sure that any all-threads-stopping doesn't try
|
||||
to move threads out of the jump pads, as it could deadlock the
|
||||
inferior (LWP could be in the jump pad, maybe even holding the
|
||||
@ -1125,6 +1131,10 @@ handle_tracepoints (struct lwp_info *lwp)
|
||||
actions. */
|
||||
tpoint_related_event |= tracepoint_was_hit (tinfo, lwp->stop_pc);
|
||||
|
||||
lwp->suspended--;
|
||||
|
||||
gdb_assert (lwp->suspended == 0);
|
||||
|
||||
if (tpoint_related_event)
|
||||
{
|
||||
if (debug_threads)
|
||||
@ -1290,7 +1300,7 @@ linux_wait_for_event_1 (ptid_t ptid, int *wstat, int options)
|
||||
/* Cancel the step-over operation --- the thread that
|
||||
started it is gone. */
|
||||
if (finish_step_over (event_child))
|
||||
unstop_all_lwps (event_child);
|
||||
unstop_all_lwps (1, event_child);
|
||||
delete_lwp (event_child);
|
||||
return lwpid;
|
||||
}
|
||||
@ -1484,6 +1494,12 @@ cancel_breakpoints_callback (struct inferior_list_entry *entry, void *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
linux_cancel_breakpoints (void)
|
||||
{
|
||||
find_inferior (&all_lwps, cancel_breakpoints_callback, NULL);
|
||||
}
|
||||
|
||||
/* Select one LWP out of those that have events pending. */
|
||||
|
||||
static void
|
||||
@ -1551,6 +1567,32 @@ gdb_wants_lwp_stopped (struct inferior_list_entry *entry)
|
||||
thread->last_resume_kind = resume_stop;
|
||||
}
|
||||
|
||||
/* Decrement the suspend count of an LWP. */
|
||||
|
||||
static int
|
||||
unsuspend_one_lwp (struct inferior_list_entry *entry, void *except)
|
||||
{
|
||||
struct lwp_info *lwp = (struct lwp_info *) entry;
|
||||
|
||||
/* Ignore EXCEPT. */
|
||||
if (lwp == except)
|
||||
return 0;
|
||||
|
||||
lwp->suspended--;
|
||||
|
||||
gdb_assert (lwp->suspended >= 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Decrement the suspend count of all LWPs, except EXCEPT, if non
|
||||
NULL. */
|
||||
|
||||
static void
|
||||
unsuspend_all_lwps (struct lwp_info *except)
|
||||
{
|
||||
find_inferior (&all_lwps, unsuspend_one_lwp, except);
|
||||
}
|
||||
|
||||
/* Set all LWP's states as "want-stopped". */
|
||||
|
||||
static void
|
||||
@ -1806,12 +1848,17 @@ linux_wait_1 (ptid_t ptid,
|
||||
(*the_low_target.set_pc) (regcache, event_child->stop_pc);
|
||||
}
|
||||
|
||||
/* We've finished stepping over a breakpoint. We've stopped all
|
||||
LWPs momentarily except the stepping one. This is where we
|
||||
resume them all again. We're going to keep waiting, so use
|
||||
proceed, which handles stepping over the next breakpoint. */
|
||||
/* We may have finished stepping over a breakpoint. If so,
|
||||
we've stopped and suspended all LWPs momentarily except the
|
||||
stepping one. This is where we resume them all again. We're
|
||||
going to keep waiting, so use proceed, which handles stepping
|
||||
over the next breakpoint. */
|
||||
if (debug_threads)
|
||||
fprintf (stderr, "proceeding all threads.\n");
|
||||
|
||||
if (step_over_finished)
|
||||
unsuspend_all_lwps (event_child);
|
||||
|
||||
proceed_all_lwps ();
|
||||
goto retry;
|
||||
}
|
||||
@ -1833,7 +1880,7 @@ linux_wait_1 (ptid_t ptid,
|
||||
if (!non_stop)
|
||||
{
|
||||
/* In all-stop, stop all threads. */
|
||||
stop_all_lwps ();
|
||||
stop_all_lwps (0, NULL);
|
||||
|
||||
/* If we're not waiting for a specific LWP, choose an event LWP
|
||||
from among those that have had events. Giving equal priority
|
||||
@ -1863,7 +1910,7 @@ linux_wait_1 (ptid_t ptid,
|
||||
threads stopped by now anyway. In non-stop, we need to
|
||||
re-resume threads that GDB wanted to be running. */
|
||||
if (step_over_finished)
|
||||
unstop_all_lwps (event_child);
|
||||
unstop_all_lwps (1, event_child);
|
||||
}
|
||||
|
||||
ourstatus->kind = TARGET_WAITKIND_STOPPED;
|
||||
@ -1912,7 +1959,8 @@ linux_wait_1 (ptid_t ptid,
|
||||
ourstatus->kind,
|
||||
ourstatus->value.sig);
|
||||
|
||||
get_lwp_thread (event_child)->last_status = *ourstatus;
|
||||
current_inferior->last_status = *ourstatus;
|
||||
|
||||
return ptid_of (event_child);
|
||||
}
|
||||
|
||||
@ -2021,15 +2069,37 @@ send_sigstop (struct lwp_info *lwp)
|
||||
kill_lwp (pid, SIGSTOP);
|
||||
}
|
||||
|
||||
static void
|
||||
send_sigstop_callback (struct inferior_list_entry *entry)
|
||||
static int
|
||||
send_sigstop_callback (struct inferior_list_entry *entry, void *except)
|
||||
{
|
||||
struct lwp_info *lwp = (struct lwp_info *) entry;
|
||||
|
||||
/* Ignore EXCEPT. */
|
||||
if (lwp == except)
|
||||
return 0;
|
||||
|
||||
if (lwp->stopped)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
send_sigstop (lwp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Increment the suspend count of an LWP, and stop it, if not stopped
|
||||
yet. */
|
||||
static int
|
||||
suspend_and_send_sigstop_callback (struct inferior_list_entry *entry,
|
||||
void *except)
|
||||
{
|
||||
struct lwp_info *lwp = (struct lwp_info *) entry;
|
||||
|
||||
/* Ignore EXCEPT. */
|
||||
if (lwp == except)
|
||||
return 0;
|
||||
|
||||
lwp->suspended++;
|
||||
|
||||
return send_sigstop_callback (entry, except);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2140,11 +2210,19 @@ wait_for_sigstop (struct inferior_list_entry *entry)
|
||||
}
|
||||
}
|
||||
|
||||
/* Stop all lwps that aren't stopped yet, except EXCEPT, if not NULL.
|
||||
If SUSPEND, then also increase the suspend count of every LWP,
|
||||
except EXCEPT. */
|
||||
|
||||
static void
|
||||
stop_all_lwps (void)
|
||||
stop_all_lwps (int suspend, struct lwp_info *except)
|
||||
{
|
||||
stopping_threads = 1;
|
||||
for_each_inferior (&all_lwps, send_sigstop_callback);
|
||||
|
||||
if (suspend)
|
||||
find_inferior (&all_lwps, suspend_and_send_sigstop_callback, except);
|
||||
else
|
||||
find_inferior (&all_lwps, send_sigstop_callback, except);
|
||||
for_each_inferior (&all_lwps, wait_for_sigstop);
|
||||
stopping_threads = 0;
|
||||
}
|
||||
@ -2227,6 +2305,9 @@ linux_resume_one_lwp (struct lwp_info *lwp,
|
||||
{
|
||||
if (step == 0)
|
||||
fprintf (stderr, "BAD - reinserting but not stepping.\n");
|
||||
if (lwp->suspended)
|
||||
fprintf (stderr, "BAD - reinserting and suspended(%d).\n",
|
||||
lwp->suspended);
|
||||
|
||||
step = 1;
|
||||
}
|
||||
@ -2423,6 +2504,17 @@ need_step_over_p (struct inferior_list_entry *entry, void *dummy)
|
||||
return 0;
|
||||
}
|
||||
|
||||
gdb_assert (lwp->suspended >= 0);
|
||||
|
||||
if (lwp->suspended)
|
||||
{
|
||||
if (debug_threads)
|
||||
fprintf (stderr,
|
||||
"Need step over [LWP %ld]? Ignoring, suspended\n",
|
||||
lwpid_of (lwp));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!lwp->need_step_over)
|
||||
{
|
||||
if (debug_threads)
|
||||
@ -2536,7 +2628,8 @@ start_step_over (struct lwp_info *lwp)
|
||||
"Starting step-over on LWP %ld. Stopping all threads\n",
|
||||
lwpid_of (lwp));
|
||||
|
||||
stop_all_lwps ();
|
||||
stop_all_lwps (1, lwp);
|
||||
gdb_assert (lwp->suspended == 0);
|
||||
|
||||
if (debug_threads)
|
||||
fprintf (stderr, "Done stopping all threads for step-over.\n");
|
||||
@ -2785,14 +2878,15 @@ linux_resume (struct thread_resume *resume_info, size_t n)
|
||||
breakpoint that needs stepping over, we start a step-over operation
|
||||
on that particular thread, and leave all others stopped. */
|
||||
|
||||
static void
|
||||
proceed_one_lwp (struct inferior_list_entry *entry)
|
||||
static int
|
||||
proceed_one_lwp (struct inferior_list_entry *entry, void *except)
|
||||
{
|
||||
struct lwp_info *lwp;
|
||||
struct lwp_info *lwp = (struct lwp_info *) entry;
|
||||
struct thread_info *thread;
|
||||
int step;
|
||||
|
||||
lwp = (struct lwp_info *) entry;
|
||||
if (lwp == except)
|
||||
return 0;
|
||||
|
||||
if (debug_threads)
|
||||
fprintf (stderr,
|
||||
@ -2802,7 +2896,7 @@ proceed_one_lwp (struct inferior_list_entry *entry)
|
||||
{
|
||||
if (debug_threads)
|
||||
fprintf (stderr, " LWP %ld already running\n", lwpid_of (lwp));
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
thread = get_lwp_thread (lwp);
|
||||
@ -2813,7 +2907,7 @@ proceed_one_lwp (struct inferior_list_entry *entry)
|
||||
if (debug_threads)
|
||||
fprintf (stderr, " client wants LWP to remain %ld stopped\n",
|
||||
lwpid_of (lwp));
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lwp->status_pending_p)
|
||||
@ -2821,14 +2915,16 @@ proceed_one_lwp (struct inferior_list_entry *entry)
|
||||
if (debug_threads)
|
||||
fprintf (stderr, " LWP %ld has pending status, leaving stopped\n",
|
||||
lwpid_of (lwp));
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
gdb_assert (lwp->suspended >= 0);
|
||||
|
||||
if (lwp->suspended)
|
||||
{
|
||||
if (debug_threads)
|
||||
fprintf (stderr, " LWP %ld is suspended\n", lwpid_of (lwp));
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (thread->last_resume_kind == resume_stop)
|
||||
@ -2854,6 +2950,21 @@ proceed_one_lwp (struct inferior_list_entry *entry)
|
||||
|
||||
step = thread->last_resume_kind == resume_step;
|
||||
linux_resume_one_lwp (lwp, step, 0, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
unsuspend_and_proceed_one_lwp (struct inferior_list_entry *entry, void *except)
|
||||
{
|
||||
struct lwp_info *lwp = (struct lwp_info *) entry;
|
||||
|
||||
if (lwp == except)
|
||||
return 0;
|
||||
|
||||
lwp->suspended--;
|
||||
gdb_assert (lwp->suspended >= 0);
|
||||
|
||||
return proceed_one_lwp (entry, except);
|
||||
}
|
||||
|
||||
/* When we finish a step-over, set threads running again. If there's
|
||||
@ -2891,7 +3002,7 @@ proceed_all_lwps (void)
|
||||
if (debug_threads)
|
||||
fprintf (stderr, "Proceeding, no step-over needed\n");
|
||||
|
||||
for_each_inferior (&all_lwps, proceed_one_lwp);
|
||||
find_inferior (&all_lwps, proceed_one_lwp, NULL);
|
||||
}
|
||||
|
||||
/* Stopped LWPs that the client wanted to be running, that don't have
|
||||
@ -2899,7 +3010,7 @@ proceed_all_lwps (void)
|
||||
NULL. This undoes a stop_all_lwps call. */
|
||||
|
||||
static void
|
||||
unstop_all_lwps (struct lwp_info *except)
|
||||
unstop_all_lwps (int unsuspend, struct lwp_info *except)
|
||||
{
|
||||
if (debug_threads)
|
||||
{
|
||||
@ -2911,14 +3022,10 @@ unstop_all_lwps (struct lwp_info *except)
|
||||
"unstopping all lwps\n");
|
||||
}
|
||||
|
||||
/* Make sure proceed_one_lwp doesn't try to resume this thread. */
|
||||
if (except != NULL)
|
||||
++except->suspended;
|
||||
|
||||
for_each_inferior (&all_lwps, proceed_one_lwp);
|
||||
|
||||
if (except != NULL)
|
||||
--except->suspended;
|
||||
if (unsuspend)
|
||||
find_inferior (&all_lwps, unsuspend_and_proceed_one_lwp, except);
|
||||
else
|
||||
find_inferior (&all_lwps, proceed_one_lwp, except);
|
||||
}
|
||||
|
||||
#ifdef HAVE_LINUX_USRREGS
|
||||
@ -4296,9 +4403,18 @@ linux_thread_stopped (struct thread_info *thread)
|
||||
/* This exposes stop-all-threads functionality to other modules. */
|
||||
|
||||
static void
|
||||
linux_pause_all (void)
|
||||
linux_pause_all (int freeze)
|
||||
{
|
||||
stop_all_lwps ();
|
||||
stop_all_lwps (freeze, NULL);
|
||||
}
|
||||
|
||||
/* This exposes unstop-all-threads functionality to other gdbserver
|
||||
modules. */
|
||||
|
||||
static void
|
||||
linux_unpause_all (int unfreeze)
|
||||
{
|
||||
unstop_all_lwps (unfreeze, NULL);
|
||||
}
|
||||
|
||||
static struct target_ops linux_target_ops = {
|
||||
@ -4351,8 +4467,10 @@ static struct target_ops linux_target_ops = {
|
||||
linux_read_pc,
|
||||
linux_write_pc,
|
||||
linux_thread_stopped,
|
||||
NULL,
|
||||
linux_pause_all,
|
||||
NULL, /* get_tib_address (Windows OS specific). */
|
||||
linux_unpause_all,
|
||||
linux_cancel_breakpoints
|
||||
};
|
||||
|
||||
static void
|
||||
|
@ -2101,7 +2101,7 @@ handle_status (char *own_buf)
|
||||
}
|
||||
else
|
||||
{
|
||||
pause_all ();
|
||||
pause_all (0);
|
||||
gdb_wants_all_threads_stopped ();
|
||||
|
||||
if (all_threads.head)
|
||||
|
@ -307,11 +307,23 @@ struct target_ops
|
||||
/* Return true if THREAD is known to be stopped now. */
|
||||
int (*thread_stopped) (struct thread_info *thread);
|
||||
|
||||
/* Pause all threads. */
|
||||
void (*pause_all) (void);
|
||||
|
||||
/* Read Thread Information Block address. */
|
||||
int (*get_tib_address) (ptid_t ptid, CORE_ADDR *address);
|
||||
|
||||
/* Pause all threads. If FREEZE, arrange for any resume attempt be
|
||||
be ignored until an unpause_all call unfreezes threads again.
|
||||
There can be nested calls to pause_all, so a freeze counter
|
||||
should be maintained. */
|
||||
void (*pause_all) (int freeze);
|
||||
|
||||
/* Unpause all threads. Threads that hadn't been resumed by the
|
||||
client should be left stopped. Basically a pause/unpause call
|
||||
pair should not end up resuming threads that were stopped before
|
||||
the pause call. */
|
||||
void (*unpause_all) (int unfreeze);
|
||||
|
||||
/* Cancel all pending breakpoints hits in all threads. */
|
||||
void (*cancel_breakpoints) (void);
|
||||
};
|
||||
|
||||
extern struct target_ops *the_target;
|
||||
@ -369,11 +381,25 @@ void set_target_ops (struct target_ops *);
|
||||
#define thread_stopped(thread) \
|
||||
(*the_target->thread_stopped) (thread)
|
||||
|
||||
#define pause_all() \
|
||||
do \
|
||||
{ \
|
||||
if (the_target->pause_all) \
|
||||
(*the_target->pause_all) (); \
|
||||
#define pause_all(freeze) \
|
||||
do \
|
||||
{ \
|
||||
if (the_target->pause_all) \
|
||||
(*the_target->pause_all) (freeze); \
|
||||
} while (0)
|
||||
|
||||
#define unpause_all(unfreeze) \
|
||||
do \
|
||||
{ \
|
||||
if (the_target->unpause_all) \
|
||||
(*the_target->unpause_all) (unfreeze); \
|
||||
} while (0)
|
||||
|
||||
#define cancel_breakpoints() \
|
||||
do \
|
||||
{ \
|
||||
if (the_target->cancel_breakpoints) \
|
||||
(*the_target->cancel_breakpoints) (); \
|
||||
} while (0)
|
||||
|
||||
/* Start non-stop mode, returns 0 on success, -1 on failure. */
|
||||
|
@ -1336,6 +1336,9 @@ clear_installed_tracepoints (void)
|
||||
struct tracepoint *tpoint;
|
||||
struct tracepoint *prev_stpoint;
|
||||
|
||||
pause_all (1);
|
||||
cancel_breakpoints ();
|
||||
|
||||
prev_stpoint = NULL;
|
||||
|
||||
/* Restore any bytes overwritten by tracepoints. */
|
||||
@ -1357,6 +1360,8 @@ clear_installed_tracepoints (void)
|
||||
delete_breakpoint (tpoint->handle);
|
||||
tpoint->handle = NULL;
|
||||
}
|
||||
|
||||
unpause_all (1);
|
||||
}
|
||||
|
||||
/* Parse a packet that defines a tracepoint. */
|
||||
@ -1656,6 +1661,9 @@ cmd_qtstart (char *packet)
|
||||
|
||||
*packet = '\0';
|
||||
|
||||
/* Pause all threads temporarily while we patch tracepoints. */
|
||||
pause_all (1);
|
||||
|
||||
/* Install tracepoints. */
|
||||
for (tpoint = tracepoints; tpoint; tpoint = tpoint->next)
|
||||
{
|
||||
@ -1686,6 +1694,7 @@ cmd_qtstart (char *packet)
|
||||
clear_installed_tracepoints ();
|
||||
if (*packet == '\0')
|
||||
write_enn (packet);
|
||||
unpause_all (1);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1697,6 +1706,8 @@ cmd_qtstart (char *packet)
|
||||
/* Tracing is now active, hits will now start being logged. */
|
||||
tracing = 1;
|
||||
|
||||
unpause_all (1);
|
||||
|
||||
write_ok (packet);
|
||||
}
|
||||
|
||||
@ -1714,6 +1725,12 @@ stop_tracing (void)
|
||||
|
||||
trace_debug ("Stopping the trace");
|
||||
|
||||
/* Pause all threads before removing breakpoints from memory. */
|
||||
pause_all (1);
|
||||
/* Since we're removing breakpoints, cancel breakpoint hits,
|
||||
possibly related to the breakpoints we're about to delete. */
|
||||
cancel_breakpoints ();
|
||||
|
||||
/* Stop logging. Tracepoints can still be hit, but they will not be
|
||||
recorded. */
|
||||
tracing = 0;
|
||||
@ -1756,6 +1773,8 @@ stop_tracing (void)
|
||||
|
||||
/* Clear out the tracepoints. */
|
||||
clear_installed_tracepoints ();
|
||||
|
||||
unpause_all (1);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1811,8 +1811,7 @@ static struct target_ops win32_target_ops = {
|
||||
NULL, /* read_pc */
|
||||
NULL, /* write_pc */
|
||||
NULL, /* thread_stopped */
|
||||
NULL, /* pause_all */
|
||||
win32_get_tib_address,
|
||||
win32_get_tib_address
|
||||
};
|
||||
|
||||
/* Initialize the Win32 backend. */
|
||||
|
Loading…
Reference in New Issue
Block a user