gdb/
2008-10-23 Pedro Alves <pedro@codesourcery.com> * defs.h: Mention ptid_is_pid. * inferior.h (ptid_is_pid): Declare. * gdbthread.h (struct thread_info) <stop_requested>: New field. (set_stop_requested): Declare. * infcmd.c (interrupt_target_1): Call set_stop_requested. * infrun.c (clear_proceed_status): Clear stop_requested. (infrun_thread_stop_requested_callback, infrun_thread_stop_requested): New. (handle_inferior_event): If a TARGET_SIGNAL_TRAP is reported on a thread that had an explicit stop request, pretend we got a TARGET_SIGNAL_0. Always stop if the thread had an explicit stop request. (print_stop_reason): In the SIGNAL_RECEIVED case, if we're not outputting to MI, and we got a TARGET_SIGNAL_0, print "# Stopped", instead of mentioning signal 0. (ptid_is_pid): New. * thread.c (set_stop_requested): New. * linux-nat.c (queued_waitpid): Rename to ... (queued_waitpid_1): ... this. Add `peek' argument. Handle it. (queued_waitpid): New, as wrapper to queued_waitpid_1. (push_waitpid): Push the SIGTRAP to the local event queue, to the kernel's. (send_sigint_callback): Delete. (linux_nat_stop_lwp): New. (linux_nat_stop): Use it. gdb/doc/ 2008-10-23 Pedro Alves <pedro@codesourcery.com> * observer.texi (thread_stop_requested): New. gdb/testsuite/ 2008-10-23 Pedro Alves <pedro@codesourcery.com> * lib/mi-support.exp (mi_expect_interrupt): Expect signal 0 instead of SIGINT.
This commit is contained in:
parent
3c0ed2996e
commit
252fbfc86a
12 changed files with 351 additions and 50 deletions
|
@ -1,3 +1,32 @@
|
|||
2008-10-23 Pedro Alves <pedro@codesourcery.com>
|
||||
|
||||
* defs.h: Mention ptid_is_pid.
|
||||
* inferior.h (ptid_is_pid): Declare.
|
||||
* gdbthread.h (struct thread_info) <stop_requested>: New field.
|
||||
(set_stop_requested): Declare.
|
||||
* infcmd.c (interrupt_target_1): Call set_stop_requested.
|
||||
* infrun.c (clear_proceed_status): Clear stop_requested.
|
||||
(infrun_thread_stop_requested_callback,
|
||||
infrun_thread_stop_requested): New.
|
||||
(handle_inferior_event): If a TARGET_SIGNAL_TRAP is reported on a
|
||||
thread that had an explicit stop request, pretend we got a
|
||||
TARGET_SIGNAL_0. Always stop if the thread had an explicit stop
|
||||
request.
|
||||
(print_stop_reason): In the SIGNAL_RECEIVED case, if we're not
|
||||
outputting to MI, and we got a TARGET_SIGNAL_0, print "# Stopped",
|
||||
instead of mentioning signal 0.
|
||||
(ptid_is_pid): New.
|
||||
* thread.c (set_stop_requested): New.
|
||||
|
||||
* linux-nat.c (queued_waitpid): Rename to ...
|
||||
(queued_waitpid_1): ... this. Add `peek' argument. Handle it.
|
||||
(queued_waitpid): New, as wrapper to queued_waitpid_1.
|
||||
(push_waitpid): Push the SIGTRAP to the local event queue, to the
|
||||
kernel's.
|
||||
(send_sigint_callback): Delete.
|
||||
(linux_nat_stop_lwp): New.
|
||||
(linux_nat_stop): Use it.
|
||||
|
||||
2008-10-23 Paul Pluzhnikov <ppluzhnikov@google.com>
|
||||
|
||||
* python/python-value (valpy_getitem): Fix heap corruption.
|
||||
|
|
|
@ -752,6 +752,7 @@ enum val_prettyprint
|
|||
ptid_get_lwp - Fetch the lwp component of a ptid.
|
||||
ptid_get_tid - Fetch the tid component of a ptid.
|
||||
ptid_equal - Test to see if two ptids are equal.
|
||||
ptid_is_pid - Test to see if this ptid represents a process id.
|
||||
|
||||
Please do NOT access the struct ptid members directly (except, of
|
||||
course, in the implementation of the above ptid manipulation
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
2008-10-23 Pedro Alves <pedro@codesourcery.com>
|
||||
|
||||
* observer.texi (thread_stop_requested): New.
|
||||
|
||||
2008-10-22 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
* gdb.texinfo (Ada Tasks, Ada Tasks and Core Files): New nodes.
|
||||
|
|
|
@ -135,6 +135,14 @@ The thread specified by @var{t} has been created.
|
|||
The thread specified by @var{t} has exited.
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun void thread_stop_requested (ptid_t @var{ptid})
|
||||
An explicit stop request was issued to @var{ptid}. If @var{ptid}
|
||||
equals @var{minus_one_ptid}, the request applied to all threads. If
|
||||
@code{ptid_is_pid(ptid)} returns true, the request applied to all
|
||||
threads of the process pointed at by @var{ptid}. Otherwise, the
|
||||
request applied to the single thread pointed at by @var{ptid}.
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun void target_resumed (ptid_t @var{ptid})
|
||||
The target was resumed. The @var{ptid} parameter specifies which
|
||||
thread was resume, and may be RESUME_ALL if all threads are resumed.
|
||||
|
|
|
@ -168,6 +168,9 @@ struct thread_info
|
|||
at. */
|
||||
bpstat stop_bpstat;
|
||||
|
||||
/* True if this thread has been explicitly requested to stop. */
|
||||
int stop_requested;
|
||||
|
||||
/* Private data used by the target vector implementation. */
|
||||
struct private_thread_info *private;
|
||||
};
|
||||
|
@ -239,6 +242,13 @@ extern void switch_to_thread (ptid_t ptid);
|
|||
If PIDGET (PTID) is -1, marks all threads. */
|
||||
extern void set_running (ptid_t ptid, int running);
|
||||
|
||||
/* Marks or clears thread(s) PTID as having been requested to stop.
|
||||
If PTID is MINUS_ONE_PTID, applies to all threads. If
|
||||
ptid_is_pid(PTID) is true, applies to all threads of the process
|
||||
pointed at by PTID. If STOP, then the THREAD_STOP_REQUESTED
|
||||
observer is called with PTID as argument. */
|
||||
extern void set_stop_requested (ptid_t ptid, int stop);
|
||||
|
||||
/* NOTE: Since the thread state is not a boolean, most times, you do
|
||||
not want to check it with negation. If you really want to check if
|
||||
the thread is stopped,
|
||||
|
|
|
@ -2245,6 +2245,15 @@ interrupt_target_1 (int all_threads)
|
|||
else
|
||||
ptid = inferior_ptid;
|
||||
target_stop (ptid);
|
||||
|
||||
/* Tag the thread as having been explicitly requested to stop, so
|
||||
other parts of gdb know not to resume this thread automatically,
|
||||
if it was stopped due to an internal event. Limit this to
|
||||
non-stop mode, as when debugging a multi-threaded application in
|
||||
all-stop mode, we will only get one stop event --- it's undefined
|
||||
which thread will report the event. */
|
||||
if (non_stop)
|
||||
set_stop_requested (ptid, 1);
|
||||
}
|
||||
|
||||
/* Stop the execution of the target while running in async mode, in
|
||||
|
|
|
@ -89,6 +89,9 @@ long ptid_get_tid (ptid_t ptid);
|
|||
/* Compare two ptids to see if they are equal */
|
||||
extern int ptid_equal (ptid_t p1, ptid_t p2);
|
||||
|
||||
/* Return true if PTID represents a process id. */
|
||||
extern int ptid_is_pid (ptid_t ptid);
|
||||
|
||||
/* Save value of inferior_ptid so that it may be restored by
|
||||
a later call to do_cleanups(). Returns the struct cleanup
|
||||
pointer needed for later doing the cleanup. */
|
||||
|
|
177
gdb/infrun.c
177
gdb/infrun.c
|
@ -1147,6 +1147,7 @@ clear_proceed_status (void)
|
|||
tp->step_range_end = 0;
|
||||
tp->step_frame_id = null_frame_id;
|
||||
tp->step_over_calls = STEP_OVER_UNDEBUGGABLE;
|
||||
tp->stop_requested = 0;
|
||||
|
||||
tp->stop_step = 0;
|
||||
|
||||
|
@ -1528,6 +1529,100 @@ static void keep_going (struct execution_control_state *ecs);
|
|||
static void print_stop_reason (enum inferior_stop_reason stop_reason,
|
||||
int stop_info);
|
||||
|
||||
/* Callback for iterate over threads. If the thread is stopped, but
|
||||
the user/frontend doesn't know about that yet, go through
|
||||
normal_stop, as if the thread had just stopped now. ARG points at
|
||||
a ptid. If PTID is MINUS_ONE_PTID, applies to all threads. If
|
||||
ptid_is_pid(PTID) is true, applies to all threads of the process
|
||||
pointed at by PTID. Otherwise, apply only to the thread pointed by
|
||||
PTID. */
|
||||
|
||||
static int
|
||||
infrun_thread_stop_requested_callback (struct thread_info *info, void *arg)
|
||||
{
|
||||
ptid_t ptid = * (ptid_t *) arg;
|
||||
|
||||
if ((ptid_equal (info->ptid, ptid)
|
||||
|| ptid_equal (minus_one_ptid, ptid)
|
||||
|| (ptid_is_pid (ptid)
|
||||
&& ptid_get_pid (ptid) == ptid_get_pid (info->ptid)))
|
||||
&& is_running (info->ptid)
|
||||
&& !is_executing (info->ptid))
|
||||
{
|
||||
struct cleanup *old_chain;
|
||||
struct execution_control_state ecss;
|
||||
struct execution_control_state *ecs = &ecss;
|
||||
|
||||
memset (ecs, 0, sizeof (*ecs));
|
||||
|
||||
old_chain = make_cleanup_restore_current_thread ();
|
||||
|
||||
switch_to_thread (info->ptid);
|
||||
|
||||
/* Go through handle_inferior_event/normal_stop, so we always
|
||||
have consistent output as if the stop event had been
|
||||
reported. */
|
||||
ecs->ptid = info->ptid;
|
||||
ecs->event_thread = find_thread_pid (info->ptid);
|
||||
ecs->ws.kind = TARGET_WAITKIND_STOPPED;
|
||||
ecs->ws.value.sig = TARGET_SIGNAL_0;
|
||||
|
||||
handle_inferior_event (ecs);
|
||||
|
||||
if (!ecs->wait_some_more)
|
||||
{
|
||||
struct thread_info *tp;
|
||||
|
||||
normal_stop ();
|
||||
|
||||
/* Finish off the continuations. The continations
|
||||
themselves are responsible for realising the thread
|
||||
didn't finish what it was supposed to do. */
|
||||
tp = inferior_thread ();
|
||||
do_all_intermediate_continuations_thread (tp);
|
||||
do_all_continuations_thread (tp);
|
||||
}
|
||||
|
||||
do_cleanups (old_chain);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This function is attached as a "thread_stop_requested" observer.
|
||||
Cleanup local state that assumed the PTID was to be resumed, and
|
||||
report the stop to the frontend. */
|
||||
|
||||
void
|
||||
infrun_thread_stop_requested (ptid_t ptid)
|
||||
{
|
||||
struct displaced_step_request *it, *next, *prev = NULL;
|
||||
|
||||
/* PTID was requested to stop. Remove it from the displaced
|
||||
stepping queue, so we don't try to resume it automatically. */
|
||||
for (it = displaced_step_request_queue; it; it = next)
|
||||
{
|
||||
next = it->next;
|
||||
|
||||
if (ptid_equal (it->ptid, ptid)
|
||||
|| ptid_equal (minus_one_ptid, ptid)
|
||||
|| (ptid_is_pid (ptid)
|
||||
&& ptid_get_pid (ptid) == ptid_get_pid (it->ptid)))
|
||||
{
|
||||
if (displaced_step_request_queue == it)
|
||||
displaced_step_request_queue = it->next;
|
||||
else
|
||||
prev->next = it->next;
|
||||
|
||||
xfree (it);
|
||||
}
|
||||
else
|
||||
prev = it;
|
||||
}
|
||||
|
||||
iterate_over_threads (infrun_thread_stop_requested_callback, &ptid);
|
||||
}
|
||||
|
||||
/* Callback for iterate_over_threads. */
|
||||
|
||||
static int
|
||||
|
@ -2279,11 +2374,21 @@ targets should add new threads to the thread list themselves in non-stop mode.")
|
|||
return;
|
||||
}
|
||||
|
||||
/* Do we need to clean up the state of a thread that has completed a
|
||||
displaced single-step? (Doing so usually affects the PC, so do
|
||||
it here, before we set stop_pc.) */
|
||||
if (ecs->ws.kind == TARGET_WAITKIND_STOPPED)
|
||||
displaced_step_fixup (ecs->ptid, ecs->event_thread->stop_signal);
|
||||
{
|
||||
/* Do we need to clean up the state of a thread that has
|
||||
completed a displaced single-step? (Doing so usually affects
|
||||
the PC, so do it here, before we set stop_pc.) */
|
||||
displaced_step_fixup (ecs->ptid, ecs->event_thread->stop_signal);
|
||||
|
||||
/* If we either finished a single-step or hit a breakpoint, but
|
||||
the user wanted this thread to be stopped, pretend we got a
|
||||
SIG0 (generic unsignaled stop). */
|
||||
|
||||
if (ecs->event_thread->stop_requested
|
||||
&& ecs->event_thread->stop_signal == TARGET_SIGNAL_TRAP)
|
||||
ecs->event_thread->stop_signal = TARGET_SIGNAL_0;
|
||||
}
|
||||
|
||||
stop_pc = regcache_read_pc (get_thread_regcache (ecs->ptid));
|
||||
|
||||
|
@ -2779,9 +2884,11 @@ process_event_stop_test:
|
|||
target_terminal_ours_for_output ();
|
||||
print_stop_reason (SIGNAL_RECEIVED, ecs->event_thread->stop_signal);
|
||||
}
|
||||
/* Always stop on signals if we're just gaining control of the
|
||||
program. */
|
||||
/* Always stop on signals if we're either just gaining control
|
||||
of the program, or the user explicitly requested this thread
|
||||
to remain stopped. */
|
||||
if (stop_soon != NO_STOP_QUIETLY
|
||||
|| ecs->event_thread->stop_requested
|
||||
|| signal_stop_state (ecs->event_thread->stop_signal))
|
||||
{
|
||||
stop_stepping (ecs);
|
||||
|
@ -3891,22 +3998,36 @@ print_stop_reason (enum inferior_stop_reason stop_reason, int stop_info)
|
|||
return_child_result_value = stop_info;
|
||||
break;
|
||||
case SIGNAL_RECEIVED:
|
||||
/* Signal received. The signal table tells us to print about
|
||||
it. */
|
||||
/* Signal received. The signal table tells us to print about
|
||||
it. */
|
||||
annotate_signal ();
|
||||
ui_out_text (uiout, "\nProgram received signal ");
|
||||
annotate_signal_name ();
|
||||
if (ui_out_is_mi_like_p (uiout))
|
||||
ui_out_field_string
|
||||
(uiout, "reason", async_reason_lookup (EXEC_ASYNC_SIGNAL_RECEIVED));
|
||||
ui_out_field_string (uiout, "signal-name",
|
||||
target_signal_to_name (stop_info));
|
||||
annotate_signal_name_end ();
|
||||
ui_out_text (uiout, ", ");
|
||||
annotate_signal_string ();
|
||||
ui_out_field_string (uiout, "signal-meaning",
|
||||
target_signal_to_string (stop_info));
|
||||
annotate_signal_string_end ();
|
||||
|
||||
if (stop_info == TARGET_SIGNAL_0 && !ui_out_is_mi_like_p (uiout))
|
||||
{
|
||||
struct thread_info *t = inferior_thread ();
|
||||
|
||||
ui_out_text (uiout, "\n[");
|
||||
ui_out_field_string (uiout, "thread-name",
|
||||
target_pid_to_str (t->ptid));
|
||||
ui_out_field_fmt (uiout, "thread-id", "] #%d", t->num);
|
||||
ui_out_text (uiout, " stopped");
|
||||
}
|
||||
else
|
||||
{
|
||||
ui_out_text (uiout, "\nProgram received signal ");
|
||||
annotate_signal_name ();
|
||||
if (ui_out_is_mi_like_p (uiout))
|
||||
ui_out_field_string
|
||||
(uiout, "reason", async_reason_lookup (EXEC_ASYNC_SIGNAL_RECEIVED));
|
||||
ui_out_field_string (uiout, "signal-name",
|
||||
target_signal_to_name (stop_info));
|
||||
annotate_signal_name_end ();
|
||||
ui_out_text (uiout, ", ");
|
||||
annotate_signal_string ();
|
||||
ui_out_field_string (uiout, "signal-meaning",
|
||||
target_signal_to_string (stop_info));
|
||||
annotate_signal_string_end ();
|
||||
}
|
||||
ui_out_text (uiout, ".\n");
|
||||
break;
|
||||
case NO_HISTORY:
|
||||
|
@ -4817,6 +4938,19 @@ ptid_equal (ptid_t ptid1, ptid_t ptid2)
|
|||
&& ptid1.tid == ptid2.tid);
|
||||
}
|
||||
|
||||
/* Returns true if PTID represents a process. */
|
||||
|
||||
int
|
||||
ptid_is_pid (ptid_t ptid)
|
||||
{
|
||||
if (ptid_equal (minus_one_ptid, ptid))
|
||||
return 0;
|
||||
if (ptid_equal (null_ptid, ptid))
|
||||
return 0;
|
||||
|
||||
return (ptid_get_lwp (ptid) == 0 && ptid_get_tid (ptid) == 0);
|
||||
}
|
||||
|
||||
/* restore_inferior_ptid() will be used by the cleanup machinery
|
||||
to restore the inferior_ptid value saved in a call to
|
||||
save_inferior_ptid(). */
|
||||
|
@ -5134,4 +5268,5 @@ Options are 'forward' or 'reverse'."),
|
|||
displaced_step_ptid = null_ptid;
|
||||
|
||||
observer_attach_thread_ptid_changed (infrun_thread_ptid_changed);
|
||||
observer_attach_thread_stop_requested (infrun_thread_stop_requested);
|
||||
}
|
||||
|
|
128
gdb/linux-nat.c
128
gdb/linux-nat.c
|
@ -316,7 +316,6 @@ static void linux_nat_async (void (*callback)
|
|||
static int linux_nat_async_mask (int mask);
|
||||
static int kill_lwp (int lwpid, int signo);
|
||||
|
||||
static int send_sigint_callback (struct lwp_info *lp, void *data);
|
||||
static int stop_callback (struct lwp_info *lp, void *data);
|
||||
|
||||
/* Captures the result of a successful waitpid call, along with the
|
||||
|
@ -333,8 +332,12 @@ struct waitpid_result
|
|||
in the async SIGCHLD handler. */
|
||||
static struct waitpid_result *waitpid_queue = NULL;
|
||||
|
||||
/* Similarly to `waitpid', but check the local event queue instead of
|
||||
querying the kernel queue. If PEEK, don't remove the event found
|
||||
from the queue. */
|
||||
|
||||
static int
|
||||
queued_waitpid (int pid, int *status, int flags)
|
||||
queued_waitpid_1 (int pid, int *status, int flags, int peek)
|
||||
{
|
||||
struct waitpid_result *msg = waitpid_queue, *prev = NULL;
|
||||
|
||||
|
@ -370,12 +373,6 @@ QWPID: linux_nat_async_events_state(%d), linux_nat_num_queued_events(%d)\n",
|
|||
{
|
||||
int pid;
|
||||
|
||||
if (prev)
|
||||
prev->next = msg->next;
|
||||
else
|
||||
waitpid_queue = msg->next;
|
||||
|
||||
msg->next = NULL;
|
||||
if (status)
|
||||
*status = msg->status;
|
||||
pid = msg->pid;
|
||||
|
@ -383,7 +380,17 @@ QWPID: linux_nat_async_events_state(%d), linux_nat_num_queued_events(%d)\n",
|
|||
if (debug_linux_nat_async)
|
||||
fprintf_unfiltered (gdb_stdlog, "QWPID: pid(%d), status(%x)\n",
|
||||
pid, msg->status);
|
||||
xfree (msg);
|
||||
|
||||
if (!peek)
|
||||
{
|
||||
if (prev)
|
||||
prev->next = msg->next;
|
||||
else
|
||||
waitpid_queue = msg->next;
|
||||
|
||||
msg->next = NULL;
|
||||
xfree (msg);
|
||||
}
|
||||
|
||||
return pid;
|
||||
}
|
||||
|
@ -396,6 +403,14 @@ QWPID: linux_nat_async_events_state(%d), linux_nat_num_queued_events(%d)\n",
|
|||
return -1;
|
||||
}
|
||||
|
||||
/* Similarly to `waitpid', but check the local event queue. */
|
||||
|
||||
static int
|
||||
queued_waitpid (int pid, int *status, int flags)
|
||||
{
|
||||
return queued_waitpid_1 (pid, status, flags, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
push_waitpid (int pid, int status, int options)
|
||||
{
|
||||
|
@ -2200,11 +2215,11 @@ stop_wait_callback (struct lwp_info *lp, void *data)
|
|||
/* There was no gdb breakpoint set at pc. Put
|
||||
the event back in the queue. */
|
||||
if (debug_linux_nat)
|
||||
fprintf_unfiltered (gdb_stdlog,
|
||||
"SWC: kill %s, %s\n",
|
||||
target_pid_to_str (lp->ptid),
|
||||
status_to_str ((int) status));
|
||||
kill_lwp (GET_LWP (lp->ptid), WSTOPSIG (status));
|
||||
fprintf_unfiltered (gdb_stdlog, "\
|
||||
SWC: leaving SIGTRAP in local queue of %s\n", target_pid_to_str (lp->ptid));
|
||||
push_waitpid (GET_LWP (lp->ptid),
|
||||
W_STOPCODE (SIGTRAP),
|
||||
lp->cloned ? __WCLONE : 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -4368,15 +4383,76 @@ linux_nat_async (void (*callback) (enum inferior_event_type event_type,
|
|||
return;
|
||||
}
|
||||
|
||||
/* Stop an LWP, and push a TARGET_SIGNAL_0 stop status if no other
|
||||
event came out. */
|
||||
|
||||
static int
|
||||
send_sigint_callback (struct lwp_info *lp, void *data)
|
||||
linux_nat_stop_lwp (struct lwp_info *lwp, void *data)
|
||||
{
|
||||
/* Use is_running instead of !lp->stopped, because the lwp may be
|
||||
stopped due to an internal event, and we want to interrupt it in
|
||||
that case too. What we want is to check if the thread is stopped
|
||||
from the point of view of the user. */
|
||||
if (is_running (lp->ptid))
|
||||
kill_lwp (GET_LWP (lp->ptid), SIGINT);
|
||||
ptid_t ptid = * (ptid_t *) data;
|
||||
|
||||
if (ptid_equal (lwp->ptid, ptid)
|
||||
|| ptid_equal (minus_one_ptid, ptid)
|
||||
|| (ptid_is_pid (ptid)
|
||||
&& ptid_get_pid (ptid) == ptid_get_pid (lwp->ptid)))
|
||||
{
|
||||
if (!lwp->stopped)
|
||||
{
|
||||
int pid, status;
|
||||
|
||||
if (debug_linux_nat)
|
||||
fprintf_unfiltered (gdb_stdlog,
|
||||
"LNSL: running -> suspending %s\n",
|
||||
target_pid_to_str (lwp->ptid));
|
||||
|
||||
/* Peek once, to check if we've already waited for this
|
||||
LWP. */
|
||||
pid = queued_waitpid_1 (ptid_get_lwp (lwp->ptid), &status,
|
||||
lwp->cloned ? __WCLONE : 0, 1 /* peek */);
|
||||
|
||||
if (pid == -1)
|
||||
{
|
||||
ptid_t ptid = lwp->ptid;
|
||||
|
||||
stop_callback (lwp, NULL);
|
||||
stop_wait_callback (lwp, NULL);
|
||||
|
||||
/* If the lwp exits while we try to stop it, there's
|
||||
nothing else to do. */
|
||||
lwp = find_lwp_pid (ptid);
|
||||
if (lwp == NULL)
|
||||
return 0;
|
||||
|
||||
pid = queued_waitpid_1 (ptid_get_lwp (lwp->ptid), &status,
|
||||
lwp->cloned ? __WCLONE : 0,
|
||||
1 /* peek */);
|
||||
}
|
||||
|
||||
/* If we didn't collect any signal other than SIGSTOP while
|
||||
stopping the LWP, push a SIGNAL_0 event. In either case,
|
||||
the event-loop will end up calling target_wait which will
|
||||
collect these. */
|
||||
if (pid == -1)
|
||||
push_waitpid (ptid_get_lwp (lwp->ptid), W_STOPCODE (0),
|
||||
lwp->cloned ? __WCLONE : 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Already known to be stopped; do nothing. */
|
||||
|
||||
if (debug_linux_nat)
|
||||
{
|
||||
if (find_thread_pid (lwp->ptid)->stop_requested)
|
||||
fprintf_unfiltered (gdb_stdlog, "\
|
||||
LNSL: already stopped/stop_requested %s\n",
|
||||
target_pid_to_str (lwp->ptid));
|
||||
else
|
||||
fprintf_unfiltered (gdb_stdlog, "\
|
||||
LNSL: already stopped/no stop_requested yet %s\n",
|
||||
target_pid_to_str (lwp->ptid));
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -4385,13 +4461,9 @@ linux_nat_stop (ptid_t ptid)
|
|||
{
|
||||
if (non_stop)
|
||||
{
|
||||
if (ptid_equal (ptid, minus_one_ptid))
|
||||
iterate_over_lwps (send_sigint_callback, &ptid);
|
||||
else
|
||||
{
|
||||
struct lwp_info *lp = find_lwp_pid (ptid);
|
||||
send_sigint_callback (lp, NULL);
|
||||
}
|
||||
linux_nat_async_events (sigchld_sync);
|
||||
iterate_over_lwps (linux_nat_stop_lwp, &ptid);
|
||||
target_async (inferior_event_handler, 0);
|
||||
}
|
||||
else
|
||||
linux_ops->to_stop (ptid);
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2008-10-23 Pedro Alves <pedro@codesourcery.com>
|
||||
|
||||
* lib/mi-support.exp (mi_expect_interrupt): Expect signal 0
|
||||
instead of SIGINT.
|
||||
|
||||
2008-10-22 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
* gdb.base/completion.exp: Update expected output following
|
||||
|
|
|
@ -1050,7 +1050,7 @@ proc mi_expect_interrupt { test } {
|
|||
set prompt_re "$mi_gdb_prompt$"
|
||||
}
|
||||
|
||||
set r "reason=\"signal-received\",signal-name=\"SIGINT\",signal-meaning=\"Interrupt\""
|
||||
set r "reason=\"signal-received\",signal-name=\"0\",signal-meaning=\"Signal 0\""
|
||||
|
||||
set any "\[^\n\]*"
|
||||
|
||||
|
|
25
gdb/thread.c
25
gdb/thread.c
|
@ -606,6 +606,31 @@ set_executing (ptid_t ptid, int executing)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
set_stop_requested (ptid_t ptid, int stop)
|
||||
{
|
||||
struct thread_info *tp;
|
||||
int all = ptid_equal (ptid, minus_one_ptid);
|
||||
|
||||
if (all || ptid_is_pid (ptid))
|
||||
{
|
||||
for (tp = thread_list; tp; tp = tp->next)
|
||||
if (all || ptid_get_pid (tp->ptid) == ptid_get_pid (ptid))
|
||||
tp->stop_requested = stop;
|
||||
}
|
||||
else
|
||||
{
|
||||
tp = find_thread_pid (ptid);
|
||||
gdb_assert (tp);
|
||||
tp->stop_requested = stop;
|
||||
}
|
||||
|
||||
/* Call the stop requested observer so other components of GDB can
|
||||
react to this request. */
|
||||
if (stop)
|
||||
observer_notify_thread_stop_requested (ptid);
|
||||
}
|
||||
|
||||
/* Prints the list of threads and their details on UIOUT.
|
||||
This is a version of 'info_thread_command' suitable for
|
||||
use from MI.
|
||||
|
|
Loading…
Reference in a new issue