mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-02-23 13:21:43 +08:00
* target.h (struct thread_resume): Delete leave_stopped member.
(struct target_ops): Add a `n' argument to the `resume' callback. * server.c (start_inferior): Adjust. (handle_v_cont, myresume): Adjust. * linux-low.c (check_removed_breakpoint): Adjust to resume interface change, and to removed leave_stopped field. (resume_ptr): Delete. (struct thread_resume_array): New. (linux_set_resume_request): Add new `arg' parameter. Adjust to resume interface change. (linux_continue_one_thread, linux_queue_one_thread) (resume_status_pending_p): Check if the resume field is NULL instead of checking the leave_stopped member. (linux_resume): Adjust to the target resume interface change. * spu-low.c (spu_resume): Adjust to the target resume interface change. * win32-low.c (win32_detach, win32_resume): Ditto.
This commit is contained in:
parent
c35fafde7c
commit
2bd7c093f6
@ -1,3 +1,23 @@
|
|||||||
|
2009-04-01 Pedro Alves <pedro@codesourcery.com>
|
||||||
|
|
||||||
|
* target.h (struct thread_resume): Delete leave_stopped member.
|
||||||
|
(struct target_ops): Add a `n' argument to the `resume' callback.
|
||||||
|
* server.c (start_inferior): Adjust.
|
||||||
|
(handle_v_cont, myresume): Adjust.
|
||||||
|
* linux-low.c (check_removed_breakpoint): Adjust to resume
|
||||||
|
interface change, and to removed leave_stopped field.
|
||||||
|
(resume_ptr): Delete.
|
||||||
|
(struct thread_resume_array): New.
|
||||||
|
(linux_set_resume_request): Add new `arg' parameter. Adjust to
|
||||||
|
resume interface change.
|
||||||
|
(linux_continue_one_thread, linux_queue_one_thread)
|
||||||
|
(resume_status_pending_p): Check if the resume field is NULL
|
||||||
|
instead of checking the leave_stopped member.
|
||||||
|
(linux_resume): Adjust to the target resume interface change.
|
||||||
|
* spu-low.c (spu_resume): Adjust to the target resume interface
|
||||||
|
change.
|
||||||
|
* win32-low.c (win32_detach, win32_resume): Ditto.
|
||||||
|
|
||||||
2009-04-01 Pedro Alves <pedro@codesourcery.com>
|
2009-04-01 Pedro Alves <pedro@codesourcery.com>
|
||||||
|
|
||||||
* linux-low.c (linux_wait_for_event): Don't clear the `stepping'
|
* linux-low.c (linux_wait_for_event): Don't clear the `stepping'
|
||||||
|
@ -116,7 +116,7 @@ static int new_inferior;
|
|||||||
|
|
||||||
static void linux_resume_one_lwp (struct inferior_list_entry *entry,
|
static void linux_resume_one_lwp (struct inferior_list_entry *entry,
|
||||||
int step, int signal, siginfo_t *info);
|
int step, int signal, siginfo_t *info);
|
||||||
static void linux_resume (struct thread_resume *resume_info);
|
static void linux_resume (struct thread_resume *resume_info, size_t n);
|
||||||
static void stop_all_lwps (void);
|
static void stop_all_lwps (void);
|
||||||
static int linux_wait_for_event (struct thread_info *child);
|
static int linux_wait_for_event (struct thread_info *child);
|
||||||
static int check_removed_breakpoint (struct lwp_info *event_child);
|
static int check_removed_breakpoint (struct lwp_info *event_child);
|
||||||
@ -952,8 +952,8 @@ linux_wait (char *status)
|
|||||||
{
|
{
|
||||||
struct thread_resume resume_info;
|
struct thread_resume resume_info;
|
||||||
resume_info.thread = -1;
|
resume_info.thread = -1;
|
||||||
resume_info.step = resume_info.sig = resume_info.leave_stopped = 0;
|
resume_info.step = resume_info.sig = 0;
|
||||||
linux_resume (&resume_info);
|
linux_resume (&resume_info, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1247,7 +1247,11 @@ linux_resume_one_lwp (struct inferior_list_entry *entry,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct thread_resume *resume_ptr;
|
struct thread_resume_array
|
||||||
|
{
|
||||||
|
struct thread_resume *resume;
|
||||||
|
size_t n;
|
||||||
|
};
|
||||||
|
|
||||||
/* This function is called once per thread. We look up the thread
|
/* This function is called once per thread. We look up the thread
|
||||||
in RESUME_PTR, and mark the thread with a pointer to the appropriate
|
in RESUME_PTR, and mark the thread with a pointer to the appropriate
|
||||||
@ -1256,21 +1260,29 @@ static struct thread_resume *resume_ptr;
|
|||||||
This algorithm is O(threads * resume elements), but resume elements
|
This algorithm is O(threads * resume elements), but resume elements
|
||||||
is small (and will remain small at least until GDB supports thread
|
is small (and will remain small at least until GDB supports thread
|
||||||
suspension). */
|
suspension). */
|
||||||
static void
|
static int
|
||||||
linux_set_resume_request (struct inferior_list_entry *entry)
|
linux_set_resume_request (struct inferior_list_entry *entry, void *arg)
|
||||||
{
|
{
|
||||||
struct lwp_info *lwp;
|
struct lwp_info *lwp;
|
||||||
struct thread_info *thread;
|
struct thread_info *thread;
|
||||||
int ndx;
|
int ndx;
|
||||||
|
struct thread_resume_array *r;
|
||||||
|
|
||||||
thread = (struct thread_info *) entry;
|
thread = (struct thread_info *) entry;
|
||||||
lwp = get_thread_lwp (thread);
|
lwp = get_thread_lwp (thread);
|
||||||
|
r = arg;
|
||||||
|
|
||||||
ndx = 0;
|
for (ndx = 0; ndx < r->n; ndx++)
|
||||||
while (resume_ptr[ndx].thread != -1 && resume_ptr[ndx].thread != entry->id)
|
if (r->resume[ndx].thread == -1 || r->resume[ndx].thread == entry->id)
|
||||||
ndx++;
|
{
|
||||||
|
lwp->resume = &r->resume[ndx];
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
lwp->resume = &resume_ptr[ndx];
|
/* No resume action for this thread. */
|
||||||
|
lwp->resume = NULL;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function is called once per thread. We check the thread's resume
|
/* This function is called once per thread. We check the thread's resume
|
||||||
@ -1289,7 +1301,7 @@ linux_continue_one_thread (struct inferior_list_entry *entry)
|
|||||||
thread = (struct thread_info *) entry;
|
thread = (struct thread_info *) entry;
|
||||||
lwp = get_thread_lwp (thread);
|
lwp = get_thread_lwp (thread);
|
||||||
|
|
||||||
if (lwp->resume->leave_stopped)
|
if (lwp->resume == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (lwp->resume->thread == -1
|
if (lwp->resume->thread == -1
|
||||||
@ -1320,7 +1332,7 @@ linux_queue_one_thread (struct inferior_list_entry *entry)
|
|||||||
thread = (struct thread_info *) entry;
|
thread = (struct thread_info *) entry;
|
||||||
lwp = get_thread_lwp (thread);
|
lwp = get_thread_lwp (thread);
|
||||||
|
|
||||||
if (lwp->resume->leave_stopped)
|
if (lwp->resume == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* If we have a new signal, enqueue the signal. */
|
/* If we have a new signal, enqueue the signal. */
|
||||||
@ -1354,7 +1366,7 @@ resume_status_pending_p (struct inferior_list_entry *entry, void *flag_p)
|
|||||||
|
|
||||||
/* Processes which will not be resumed are not interesting, because
|
/* Processes which will not be resumed are not interesting, because
|
||||||
we might not wait for them next time through linux_wait. */
|
we might not wait for them next time through linux_wait. */
|
||||||
if (lwp->resume->leave_stopped)
|
if (lwp->resume == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* If this thread has a removed breakpoint, we won't have any
|
/* If this thread has a removed breakpoint, we won't have any
|
||||||
@ -1375,14 +1387,12 @@ resume_status_pending_p (struct inferior_list_entry *entry, void *flag_p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
linux_resume (struct thread_resume *resume_info)
|
linux_resume (struct thread_resume *resume_info, size_t n)
|
||||||
{
|
{
|
||||||
int pending_flag;
|
int pending_flag;
|
||||||
|
struct thread_resume_array array = { resume_info, n };
|
||||||
|
|
||||||
/* Yes, the use of a global here is rather ugly. */
|
find_inferior (&all_threads, linux_set_resume_request, &array);
|
||||||
resume_ptr = resume_info;
|
|
||||||
|
|
||||||
for_each_inferior (&all_threads, linux_set_resume_request);
|
|
||||||
|
|
||||||
/* If there is a thread which would otherwise be resumed, which
|
/* If there is a thread which would otherwise be resumed, which
|
||||||
has a pending status, then don't resume any threads - we can just
|
has a pending status, then don't resume any threads - we can just
|
||||||
|
@ -146,7 +146,6 @@ start_inferior (char **argv, char *statusptr)
|
|||||||
resume_info.thread = -1;
|
resume_info.thread = -1;
|
||||||
resume_info.step = 0;
|
resume_info.step = 0;
|
||||||
resume_info.sig = 0;
|
resume_info.sig = 0;
|
||||||
resume_info.leave_stopped = 0;
|
|
||||||
|
|
||||||
sig = mywait (statusptr, 0);
|
sig = mywait (statusptr, 0);
|
||||||
if (*statusptr != 'T')
|
if (*statusptr != 'T')
|
||||||
@ -154,7 +153,7 @@ start_inferior (char **argv, char *statusptr)
|
|||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
(*the_target->resume) (&resume_info);
|
(*the_target->resume) (&resume_info, 1);
|
||||||
|
|
||||||
sig = mywait (statusptr, 0);
|
sig = mywait (statusptr, 0);
|
||||||
if (*statusptr != 'T')
|
if (*statusptr != 'T')
|
||||||
@ -1056,7 +1055,8 @@ handle_v_cont (char *own_buf, char *status, int *signal)
|
|||||||
{
|
{
|
||||||
char *p, *q;
|
char *p, *q;
|
||||||
int n = 0, i = 0;
|
int n = 0, i = 0;
|
||||||
struct thread_resume *resume_info, default_action;
|
struct thread_resume *resume_info;
|
||||||
|
struct thread_resume default_action = {0};
|
||||||
|
|
||||||
/* Count the number of semicolons in the packet. There should be one
|
/* Count the number of semicolons in the packet. There should be one
|
||||||
for every action. */
|
for every action. */
|
||||||
@ -1067,26 +1067,16 @@ handle_v_cont (char *own_buf, char *status, int *signal)
|
|||||||
p++;
|
p++;
|
||||||
p = strchr (p, ';');
|
p = strchr (p, ';');
|
||||||
}
|
}
|
||||||
/* Allocate room for one extra action, for the default remain-stopped
|
|
||||||
behavior; if no default action is in the list, we'll need the extra
|
resume_info = malloc (n * sizeof (resume_info[0]));
|
||||||
slot. */
|
|
||||||
resume_info = malloc ((n + 1) * sizeof (resume_info[0]));
|
|
||||||
if (resume_info == NULL)
|
if (resume_info == NULL)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
default_action.thread = -1;
|
|
||||||
default_action.leave_stopped = 1;
|
|
||||||
default_action.step = 0;
|
|
||||||
default_action.sig = 0;
|
|
||||||
|
|
||||||
p = &own_buf[5];
|
p = &own_buf[5];
|
||||||
i = 0;
|
|
||||||
while (*p)
|
while (*p)
|
||||||
{
|
{
|
||||||
p++;
|
p++;
|
||||||
|
|
||||||
resume_info[i].leave_stopped = 0;
|
|
||||||
|
|
||||||
if (p[0] == 's' || p[0] == 'S')
|
if (p[0] == 's' || p[0] == 'S')
|
||||||
resume_info[i].step = 1;
|
resume_info[i].step = 1;
|
||||||
else if (p[0] == 'c' || p[0] == 'C')
|
else if (p[0] == 'c' || p[0] == 'C')
|
||||||
@ -1141,7 +1131,8 @@ handle_v_cont (char *own_buf, char *status, int *signal)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resume_info[i] = default_action;
|
if (i < n)
|
||||||
|
resume_info[i] = default_action;
|
||||||
|
|
||||||
/* Still used in occasional places in the backend. */
|
/* Still used in occasional places in the backend. */
|
||||||
if (n == 1 && resume_info[0].thread != -1)
|
if (n == 1 && resume_info[0].thread != -1)
|
||||||
@ -1151,7 +1142,7 @@ handle_v_cont (char *own_buf, char *status, int *signal)
|
|||||||
set_desired_inferior (0);
|
set_desired_inferior (0);
|
||||||
|
|
||||||
enable_async_io ();
|
enable_async_io ();
|
||||||
(*the_target->resume) (resume_info);
|
(*the_target->resume) (resume_info, n);
|
||||||
|
|
||||||
free (resume_info);
|
free (resume_info);
|
||||||
|
|
||||||
@ -1333,25 +1324,31 @@ myresume (char *own_buf, int step, int *signalp, char *statusp)
|
|||||||
struct thread_resume resume_info[2];
|
struct thread_resume resume_info[2];
|
||||||
int n = 0;
|
int n = 0;
|
||||||
int sig = *signalp;
|
int sig = *signalp;
|
||||||
|
int valid_cont_thread;
|
||||||
|
|
||||||
set_desired_inferior (0);
|
set_desired_inferior (0);
|
||||||
|
|
||||||
if (step || sig || (cont_thread != 0 && cont_thread != -1))
|
valid_cont_thread = (cont_thread != 0 && cont_thread != -1);
|
||||||
|
|
||||||
|
if (step || sig || valid_cont_thread)
|
||||||
{
|
{
|
||||||
resume_info[0].thread
|
resume_info[0].thread
|
||||||
= ((struct inferior_list_entry *) current_inferior)->id;
|
= ((struct inferior_list_entry *) current_inferior)->id;
|
||||||
resume_info[0].step = step;
|
resume_info[0].step = step;
|
||||||
resume_info[0].sig = sig;
|
resume_info[0].sig = sig;
|
||||||
resume_info[0].leave_stopped = 0;
|
|
||||||
n++;
|
n++;
|
||||||
}
|
}
|
||||||
resume_info[n].thread = -1;
|
|
||||||
resume_info[n].step = 0;
|
if (!valid_cont_thread)
|
||||||
resume_info[n].sig = 0;
|
{
|
||||||
resume_info[n].leave_stopped = (cont_thread != 0 && cont_thread != -1);
|
resume_info[n].thread = -1;
|
||||||
|
resume_info[n].step = 0;
|
||||||
|
resume_info[n].sig = 0;
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
|
||||||
enable_async_io ();
|
enable_async_io ();
|
||||||
(*the_target->resume) (resume_info);
|
(*the_target->resume) (resume_info, n);
|
||||||
*signalp = mywait (statusp, 1);
|
*signalp = mywait (statusp, 1);
|
||||||
prepare_resume_reply (own_buf, *statusp, *signalp);
|
prepare_resume_reply (own_buf, *statusp, *signalp);
|
||||||
disable_async_io ();
|
disable_async_io ();
|
||||||
|
@ -345,24 +345,27 @@ spu_thread_alive (unsigned long tid)
|
|||||||
|
|
||||||
/* Resume process. */
|
/* Resume process. */
|
||||||
static void
|
static void
|
||||||
spu_resume (struct thread_resume *resume_info)
|
spu_resume (struct thread_resume *resume_info, size_t n)
|
||||||
{
|
{
|
||||||
while (resume_info->thread != -1
|
size_t i;
|
||||||
&& resume_info->thread != current_tid)
|
|
||||||
resume_info++;
|
|
||||||
|
|
||||||
if (resume_info->leave_stopped)
|
for (i = 0; i < n; i++)
|
||||||
|
if (resume_info[i].thread == -1
|
||||||
|
|| resume_info[i].thread == current_tid)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (i == n)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* We don't support hardware single-stepping right now, assume
|
/* We don't support hardware single-stepping right now, assume
|
||||||
GDB knows to use software single-stepping. */
|
GDB knows to use software single-stepping. */
|
||||||
if (resume_info->step)
|
if (resume_info[i].step)
|
||||||
fprintf (stderr, "Hardware single-step not supported.\n");
|
fprintf (stderr, "Hardware single-step not supported.\n");
|
||||||
|
|
||||||
regcache_invalidate ();
|
regcache_invalidate ();
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
ptrace (PTRACE_CONT, current_tid, 0, resume_info->sig);
|
ptrace (PTRACE_CONT, current_tid, 0, resume_info[i].sig);
|
||||||
if (errno)
|
if (errno)
|
||||||
perror_with_name ("ptrace");
|
perror_with_name ("ptrace");
|
||||||
}
|
}
|
||||||
|
@ -22,18 +22,15 @@
|
|||||||
#ifndef TARGET_H
|
#ifndef TARGET_H
|
||||||
#define TARGET_H
|
#define TARGET_H
|
||||||
|
|
||||||
/* This structure describes how to resume a particular thread (or
|
/* This structure describes how to resume a particular thread (or all
|
||||||
all threads) based on the client's request. If thread is -1, then
|
threads) based on the client's request. If thread is -1, then this
|
||||||
this entry applies to all threads. These are generally passed around
|
entry applies to all threads. These are passed around as an
|
||||||
as an array, and terminated by a thread == -1 entry. */
|
array. */
|
||||||
|
|
||||||
struct thread_resume
|
struct thread_resume
|
||||||
{
|
{
|
||||||
unsigned long thread;
|
unsigned long thread;
|
||||||
|
|
||||||
/* If non-zero, leave this thread stopped. */
|
|
||||||
int leave_stopped;
|
|
||||||
|
|
||||||
/* If non-zero, we want to single-step. */
|
/* If non-zero, we want to single-step. */
|
||||||
int step;
|
int step;
|
||||||
|
|
||||||
@ -83,7 +80,7 @@ struct target_ops
|
|||||||
|
|
||||||
/* Resume the inferior process. */
|
/* Resume the inferior process. */
|
||||||
|
|
||||||
void (*resume) (struct thread_resume *resume_info);
|
void (*resume) (struct thread_resume *resume_info, size_t n);
|
||||||
|
|
||||||
/* Wait for the inferior process to change state.
|
/* Wait for the inferior process to change state.
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ typedef BOOL WINAPI (*winapi_DebugSetProcessKillOnExit) (BOOL KillOnExit);
|
|||||||
typedef BOOL WINAPI (*winapi_DebugBreakProcess) (HANDLE);
|
typedef BOOL WINAPI (*winapi_DebugBreakProcess) (HANDLE);
|
||||||
typedef BOOL WINAPI (*winapi_GenerateConsoleCtrlEvent) (DWORD, DWORD);
|
typedef BOOL WINAPI (*winapi_GenerateConsoleCtrlEvent) (DWORD, DWORD);
|
||||||
|
|
||||||
static void win32_resume (struct thread_resume *resume_info);
|
static void win32_resume (struct thread_resume *resume_info, size_t n);
|
||||||
|
|
||||||
/* Get the thread ID from the current selected inferior (the current
|
/* Get the thread ID from the current selected inferior (the current
|
||||||
thread). */
|
thread). */
|
||||||
@ -726,8 +726,7 @@ win32_detach (void)
|
|||||||
resume.thread = -1;
|
resume.thread = -1;
|
||||||
resume.step = 0;
|
resume.step = 0;
|
||||||
resume.sig = 0;
|
resume.sig = 0;
|
||||||
resume.leave_stopped = 0;
|
win32_resume (&resume, 1);
|
||||||
win32_resume (&resume);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!DebugActiveProcessStop (current_process_id))
|
if (!DebugActiveProcessStop (current_process_id))
|
||||||
@ -771,7 +770,7 @@ win32_thread_alive (unsigned long tid)
|
|||||||
/* Resume the inferior process. RESUME_INFO describes how we want
|
/* Resume the inferior process. RESUME_INFO describes how we want
|
||||||
to resume. */
|
to resume. */
|
||||||
static void
|
static void
|
||||||
win32_resume (struct thread_resume *resume_info)
|
win32_resume (struct thread_resume *resume_info, size_t n)
|
||||||
{
|
{
|
||||||
DWORD tid;
|
DWORD tid;
|
||||||
enum target_signal sig;
|
enum target_signal sig;
|
||||||
@ -782,9 +781,9 @@ win32_resume (struct thread_resume *resume_info)
|
|||||||
/* This handles the very limited set of resume packets that GDB can
|
/* This handles the very limited set of resume packets that GDB can
|
||||||
currently produce. */
|
currently produce. */
|
||||||
|
|
||||||
if (resume_info[0].thread == -1)
|
if (n == 1 && resume_info[0].thread == -1)
|
||||||
tid = -1;
|
tid = -1;
|
||||||
else if (resume_info[1].thread == -1 && !resume_info[1].leave_stopped)
|
else if (n > 1)
|
||||||
tid = -1;
|
tid = -1;
|
||||||
else
|
else
|
||||||
/* Yes, we're ignoring resume_info[0].thread. It'd be tricky to make
|
/* Yes, we're ignoring resume_info[0].thread. It'd be tricky to make
|
||||||
|
Loading…
Reference in New Issue
Block a user