* linux-nat.c (struct saved_ptids, threads_to_delete)
(record_dead_thread, prune_lwps, find_thread_from_lwp) (exit_lwp): New. (linux_nat_resume): Call prune_lwps. (wait_lwp, linux_nat_wait): Call exit_lwp.
This commit is contained in:
parent
46e9880c62
commit
e26af52fd1
2 changed files with 101 additions and 32 deletions
|
@ -1,3 +1,11 @@
|
|||
2006-02-01 Daniel Jacobowitz <dan@codesourcery.com>
|
||||
|
||||
* linux-nat.c (struct saved_ptids, threads_to_delete)
|
||||
(record_dead_thread, prune_lwps, find_thread_from_lwp)
|
||||
(exit_lwp): New.
|
||||
(linux_nat_resume): Call prune_lwps.
|
||||
(wait_lwp, linux_nat_wait): Call exit_lwp.
|
||||
|
||||
2006-02-01 Daniel Jacobowitz <dan@codesourcery.com>
|
||||
|
||||
* printcmd.c (printf_command): Make format string checking
|
||||
|
|
125
gdb/linux-nat.c
125
gdb/linux-nat.c
|
@ -1,6 +1,7 @@
|
|||
/* GNU/Linux native-dependent code common to multiple platforms.
|
||||
|
||||
Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
|
@ -868,6 +869,92 @@ iterate_over_lwps (int (*callback) (struct lwp_info *, void *), void *data)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Record a PTID for later deletion. */
|
||||
|
||||
struct saved_ptids
|
||||
{
|
||||
ptid_t ptid;
|
||||
struct saved_ptids *next;
|
||||
};
|
||||
static struct saved_ptids *threads_to_delete;
|
||||
|
||||
static void
|
||||
record_dead_thread (ptid_t ptid)
|
||||
{
|
||||
struct saved_ptids *p = xmalloc (sizeof (struct saved_ptids));
|
||||
p->ptid = ptid;
|
||||
p->next = threads_to_delete;
|
||||
threads_to_delete = p;
|
||||
}
|
||||
|
||||
/* Delete any dead threads which are not the current thread. */
|
||||
|
||||
static void
|
||||
prune_lwps (void)
|
||||
{
|
||||
struct saved_ptids **p = &threads_to_delete;
|
||||
|
||||
while (*p)
|
||||
if (! ptid_equal ((*p)->ptid, inferior_ptid))
|
||||
{
|
||||
struct saved_ptids *tmp = *p;
|
||||
delete_thread (tmp->ptid);
|
||||
*p = tmp->next;
|
||||
xfree (tmp);
|
||||
}
|
||||
else
|
||||
p = &(*p)->next;
|
||||
}
|
||||
|
||||
/* Callback for iterate_over_threads that finds a thread corresponding
|
||||
to the given LWP. */
|
||||
|
||||
static int
|
||||
find_thread_from_lwp (struct thread_info *thr, void *dummy)
|
||||
{
|
||||
ptid_t *ptid_p = dummy;
|
||||
|
||||
if (GET_LWP (thr->ptid) && GET_LWP (thr->ptid) == GET_LWP (*ptid_p))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Handle the exit of a single thread LP. */
|
||||
|
||||
static void
|
||||
exit_lwp (struct lwp_info *lp)
|
||||
{
|
||||
if (in_thread_list (lp->ptid))
|
||||
{
|
||||
/* Core GDB cannot deal with us deleting the current thread. */
|
||||
if (!ptid_equal (lp->ptid, inferior_ptid))
|
||||
delete_thread (lp->ptid);
|
||||
else
|
||||
record_dead_thread (lp->ptid);
|
||||
printf_unfiltered (_("[%s exited]\n"),
|
||||
target_pid_to_str (lp->ptid));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Even if LP->PTID is not in the global GDB thread list, the
|
||||
LWP may be - with an additional thread ID. We don't need
|
||||
to print anything in this case; thread_db is in use and
|
||||
already took care of that. But it didn't delete the thread
|
||||
in order to handle zombies correctly. */
|
||||
|
||||
struct thread_info *thr;
|
||||
|
||||
thr = iterate_over_threads (find_thread_from_lwp, &lp->ptid);
|
||||
if (thr && !ptid_equal (thr->ptid, inferior_ptid))
|
||||
delete_thread (thr->ptid);
|
||||
else
|
||||
record_dead_thread (thr->ptid);
|
||||
}
|
||||
|
||||
delete_lwp (lp->ptid);
|
||||
}
|
||||
|
||||
/* Attach to the LWP specified by PID. If VERBOSE is non-zero, print
|
||||
a message telling the user that a new LWP has been added to the
|
||||
process. */
|
||||
|
@ -1121,6 +1208,8 @@ linux_nat_resume (ptid_t ptid, int step, enum target_signal signo)
|
|||
signo ? strsignal (signo) : "0",
|
||||
target_pid_to_str (inferior_ptid));
|
||||
|
||||
prune_lwps ();
|
||||
|
||||
/* A specific PTID means `step only this process id'. */
|
||||
resume_all = (PIDGET (ptid) == -1);
|
||||
|
||||
|
@ -1321,16 +1410,7 @@ wait_lwp (struct lwp_info *lp)
|
|||
|
||||
if (thread_dead)
|
||||
{
|
||||
if (in_thread_list (lp->ptid))
|
||||
{
|
||||
/* Core GDB cannot deal with us deleting the current thread. */
|
||||
if (!ptid_equal (lp->ptid, inferior_ptid))
|
||||
delete_thread (lp->ptid);
|
||||
printf_unfiltered (_("[%s exited]\n"),
|
||||
target_pid_to_str (lp->ptid));
|
||||
}
|
||||
|
||||
delete_lwp (lp->ptid);
|
||||
exit_lwp (lp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2117,16 +2197,6 @@ retry:
|
|||
/* Check if the thread has exited. */
|
||||
if ((WIFEXITED (status) || WIFSIGNALED (status)) && num_lwps > 1)
|
||||
{
|
||||
if (in_thread_list (lp->ptid))
|
||||
{
|
||||
/* Core GDB cannot deal with us deleting the current
|
||||
thread. */
|
||||
if (!ptid_equal (lp->ptid, inferior_ptid))
|
||||
delete_thread (lp->ptid);
|
||||
printf_unfiltered (_("[%s exited]\n"),
|
||||
target_pid_to_str (lp->ptid));
|
||||
}
|
||||
|
||||
/* If this is the main thread, we must stop all threads and
|
||||
verify if they are still alive. This is because in the nptl
|
||||
thread model, there is no signal issued for exiting LWPs
|
||||
|
@ -2148,7 +2218,7 @@ retry:
|
|||
"LLW: %s exited.\n",
|
||||
target_pid_to_str (lp->ptid));
|
||||
|
||||
delete_lwp (lp->ptid);
|
||||
exit_lwp (lp);
|
||||
|
||||
/* If there is at least one more LWP, then the exit signal
|
||||
was not the end of the debugged application and should be
|
||||
|
@ -2170,21 +2240,12 @@ retry:
|
|||
has stopped. A similar check is made in stop_wait_callback(). */
|
||||
if (num_lwps > 1 && !linux_nat_thread_alive (lp->ptid))
|
||||
{
|
||||
if (in_thread_list (lp->ptid))
|
||||
{
|
||||
/* Core GDB cannot deal with us deleting the current
|
||||
thread. */
|
||||
if (!ptid_equal (lp->ptid, inferior_ptid))
|
||||
delete_thread (lp->ptid);
|
||||
printf_unfiltered (_("[%s exited]\n"),
|
||||
target_pid_to_str (lp->ptid));
|
||||
}
|
||||
if (debug_linux_nat)
|
||||
fprintf_unfiltered (gdb_stdlog,
|
||||
"LLW: %s exited.\n",
|
||||
target_pid_to_str (lp->ptid));
|
||||
|
||||
delete_lwp (lp->ptid);
|
||||
exit_lwp (lp);
|
||||
|
||||
/* Make sure there is at least one thread running. */
|
||||
gdb_assert (iterate_over_lwps (running_callback, NULL));
|
||||
|
|
Loading…
Reference in a new issue