mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-01 20:12:01 +08:00
* 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:
@ -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>
|
2006-02-01 Daniel Jacobowitz <dan@codesourcery.com>
|
||||||
|
|
||||||
* printcmd.c (printf_command): Make format string checking
|
* 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.
|
/* 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.
|
This file is part of GDB.
|
||||||
|
|
||||||
@ -868,6 +869,92 @@ iterate_over_lwps (int (*callback) (struct lwp_info *, void *), void *data)
|
|||||||
return NULL;
|
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
|
/* 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
|
a message telling the user that a new LWP has been added to the
|
||||||
process. */
|
process. */
|
||||||
@ -1121,6 +1208,8 @@ linux_nat_resume (ptid_t ptid, int step, enum target_signal signo)
|
|||||||
signo ? strsignal (signo) : "0",
|
signo ? strsignal (signo) : "0",
|
||||||
target_pid_to_str (inferior_ptid));
|
target_pid_to_str (inferior_ptid));
|
||||||
|
|
||||||
|
prune_lwps ();
|
||||||
|
|
||||||
/* A specific PTID means `step only this process id'. */
|
/* A specific PTID means `step only this process id'. */
|
||||||
resume_all = (PIDGET (ptid) == -1);
|
resume_all = (PIDGET (ptid) == -1);
|
||||||
|
|
||||||
@ -1321,16 +1410,7 @@ wait_lwp (struct lwp_info *lp)
|
|||||||
|
|
||||||
if (thread_dead)
|
if (thread_dead)
|
||||||
{
|
{
|
||||||
if (in_thread_list (lp->ptid))
|
exit_lwp (lp);
|
||||||
{
|
|
||||||
/* 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);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2117,16 +2197,6 @@ retry:
|
|||||||
/* Check if the thread has exited. */
|
/* Check if the thread has exited. */
|
||||||
if ((WIFEXITED (status) || WIFSIGNALED (status)) && num_lwps > 1)
|
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
|
/* If this is the main thread, we must stop all threads and
|
||||||
verify if they are still alive. This is because in the nptl
|
verify if they are still alive. This is because in the nptl
|
||||||
thread model, there is no signal issued for exiting LWPs
|
thread model, there is no signal issued for exiting LWPs
|
||||||
@ -2148,7 +2218,7 @@ retry:
|
|||||||
"LLW: %s exited.\n",
|
"LLW: %s exited.\n",
|
||||||
target_pid_to_str (lp->ptid));
|
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
|
/* If there is at least one more LWP, then the exit signal
|
||||||
was not the end of the debugged application and should be
|
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(). */
|
has stopped. A similar check is made in stop_wait_callback(). */
|
||||||
if (num_lwps > 1 && !linux_nat_thread_alive (lp->ptid))
|
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)
|
if (debug_linux_nat)
|
||||||
fprintf_unfiltered (gdb_stdlog,
|
fprintf_unfiltered (gdb_stdlog,
|
||||||
"LLW: %s exited.\n",
|
"LLW: %s exited.\n",
|
||||||
target_pid_to_str (lp->ptid));
|
target_pid_to_str (lp->ptid));
|
||||||
|
|
||||||
delete_lwp (lp->ptid);
|
exit_lwp (lp);
|
||||||
|
|
||||||
/* Make sure there is at least one thread running. */
|
/* Make sure there is at least one thread running. */
|
||||||
gdb_assert (iterate_over_lwps (running_callback, NULL));
|
gdb_assert (iterate_over_lwps (running_callback, NULL));
|
||||||
|
Reference in New Issue
Block a user