mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-08-01 17:27:15 +08:00
* linux-nat.h (linux_proc_get_tgid): Declare.
* linux-nat.c (linux_proc_get_tgid): New. * linux-thread-db.c (struct thread_db_info): New field `need_stale_parent_threads_check'. (add_thread_db_info): Set it. (find_new_threads_callback): Ignore stale fork parent threads. (thread_db_resume): New. (init_thread_db_ops): Install thread_db_resume.
This commit is contained in:
@ -1,3 +1,14 @@
|
|||||||
|
2009-05-18 Pedro Alves <pedro@codesourcery.com>
|
||||||
|
|
||||||
|
* linux-nat.h (linux_proc_get_tgid): Declare.
|
||||||
|
* linux-nat.c (linux_proc_get_tgid): New.
|
||||||
|
* linux-thread-db.c (struct thread_db_info): New field
|
||||||
|
`need_stale_parent_threads_check'.
|
||||||
|
(add_thread_db_info): Set it.
|
||||||
|
(find_new_threads_callback): Ignore stale fork parent threads.
|
||||||
|
(thread_db_resume): New.
|
||||||
|
(init_thread_db_ops): Install thread_db_resume.
|
||||||
|
|
||||||
2009-05-18 Pedro Alves <pedro@codesourcery.com>
|
2009-05-18 Pedro Alves <pedro@codesourcery.com>
|
||||||
|
|
||||||
* fork-child.c (fork_inferior): Only reset the thread list if this
|
* fork-child.c (fork_inferior): Only reset the thread list if this
|
||||||
|
@ -1129,6 +1129,34 @@ exit_lwp (struct lwp_info *lp)
|
|||||||
delete_lwp (lp->ptid);
|
delete_lwp (lp->ptid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return an lwp's tgid, found in `/proc/PID/status'. */
|
||||||
|
|
||||||
|
int
|
||||||
|
linux_proc_get_tgid (int lwpid)
|
||||||
|
{
|
||||||
|
FILE *status_file;
|
||||||
|
char buf[100];
|
||||||
|
int tgid = -1;
|
||||||
|
|
||||||
|
snprintf (buf, sizeof (buf), "/proc/%d/status", (int) lwpid);
|
||||||
|
status_file = fopen (buf, "r");
|
||||||
|
if (status_file != NULL)
|
||||||
|
{
|
||||||
|
while (fgets (buf, sizeof (buf), status_file))
|
||||||
|
{
|
||||||
|
if (strncmp (buf, "Tgid:", 5) == 0)
|
||||||
|
{
|
||||||
|
tgid = strtoul (buf + strlen ("Tgid:"), NULL, 10);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose (status_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
return tgid;
|
||||||
|
}
|
||||||
|
|
||||||
/* Detect `T (stopped)' in `/proc/PID/status'.
|
/* Detect `T (stopped)' in `/proc/PID/status'.
|
||||||
Other states including `T (tracing stop)' are reported as false. */
|
Other states including `T (tracing stop)' are reported as false. */
|
||||||
|
|
||||||
|
@ -99,6 +99,10 @@ int thread_db_attach_lwp (ptid_t ptid);
|
|||||||
/* Find process PID's pending signal set from /proc/pid/status. */
|
/* Find process PID's pending signal set from /proc/pid/status. */
|
||||||
void linux_proc_pending_signals (int pid, sigset_t *pending, sigset_t *blocked, sigset_t *ignored);
|
void linux_proc_pending_signals (int pid, sigset_t *pending, sigset_t *blocked, sigset_t *ignored);
|
||||||
|
|
||||||
|
/* Return the TGID of LWPID from /proc/pid/status. Returns -1 if not
|
||||||
|
found. */
|
||||||
|
extern int linux_proc_get_tgid (int lwpid);
|
||||||
|
|
||||||
/* linux-nat functions for handling fork events. */
|
/* linux-nat functions for handling fork events. */
|
||||||
extern void linux_enable_event_reporting (ptid_t ptid);
|
extern void linux_enable_event_reporting (ptid_t ptid);
|
||||||
|
|
||||||
|
@ -104,6 +104,13 @@ struct thread_db_info
|
|||||||
/* Connection to the libthread_db library. */
|
/* Connection to the libthread_db library. */
|
||||||
td_thragent_t *thread_agent;
|
td_thragent_t *thread_agent;
|
||||||
|
|
||||||
|
/* True if we need to apply the workaround for glibc/BZ5983. When
|
||||||
|
we catch a PTRACE_O_TRACEFORK, and go query the child's thread
|
||||||
|
list, nptl_db returns the parent's threads in addition to the new
|
||||||
|
(single) child thread. If this flag is set, we do extra work to
|
||||||
|
be able to ignore such stale entries. */
|
||||||
|
int need_stale_parent_threads_check;
|
||||||
|
|
||||||
/* Location of the thread creation event breakpoint. The code at
|
/* Location of the thread creation event breakpoint. The code at
|
||||||
this location in the child process will be called by the pthread
|
this location in the child process will be called by the pthread
|
||||||
library whenever a new thread is created. By setting a special
|
library whenever a new thread is created. By setting a special
|
||||||
@ -168,6 +175,7 @@ add_thread_db_info (void *handle)
|
|||||||
info = xcalloc (1, sizeof (*info));
|
info = xcalloc (1, sizeof (*info));
|
||||||
info->pid = ptid_get_pid (inferior_ptid);
|
info->pid = ptid_get_pid (inferior_ptid);
|
||||||
info->handle = handle;
|
info->handle = handle;
|
||||||
|
info->need_stale_parent_threads_check = 1;
|
||||||
|
|
||||||
info->next = thread_db_list;
|
info->next = thread_db_list;
|
||||||
thread_db_list = info;
|
thread_db_list = info;
|
||||||
@ -1269,8 +1277,6 @@ find_new_threads_callback (const td_thrhandle_t *th_p, void *data)
|
|||||||
if (ti.ti_state == TD_THR_UNKNOWN || ti.ti_state == TD_THR_ZOMBIE)
|
if (ti.ti_state == TD_THR_UNKNOWN || ti.ti_state == TD_THR_ZOMBIE)
|
||||||
return 0; /* A zombie -- ignore. */
|
return 0; /* A zombie -- ignore. */
|
||||||
|
|
||||||
ptid = ptid_build (info->pid, ti.ti_lid, 0);
|
|
||||||
|
|
||||||
if (ti.ti_tid == 0)
|
if (ti.ti_tid == 0)
|
||||||
{
|
{
|
||||||
/* A thread ID of zero means that this is the main thread, but
|
/* A thread ID of zero means that this is the main thread, but
|
||||||
@ -1279,14 +1285,29 @@ find_new_threads_callback (const td_thrhandle_t *th_p, void *data)
|
|||||||
be yet. Just enable event reporting and otherwise ignore
|
be yet. Just enable event reporting and otherwise ignore
|
||||||
it. */
|
it. */
|
||||||
|
|
||||||
|
/* In that case, we're not stopped in a fork syscall and don't
|
||||||
|
need this glibc bug workaround. */
|
||||||
|
info->need_stale_parent_threads_check = 0;
|
||||||
|
|
||||||
err = info->td_thr_event_enable_p (th_p, 1);
|
err = info->td_thr_event_enable_p (th_p, 1);
|
||||||
if (err != TD_OK)
|
if (err != TD_OK)
|
||||||
error (_("Cannot enable thread event reporting for %s: %s"),
|
error (_("Cannot enable thread event reporting for LWP %d: %s"),
|
||||||
target_pid_to_str (ptid), thread_db_err_str (err));
|
(int) ti.ti_lid, thread_db_err_str (err));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Ignore stale parent threads, caused by glibc/BZ5983. This is a
|
||||||
|
bit expensive, as it needs to open /proc/pid/status, so try to
|
||||||
|
avoid doing the work if we know we don't have to. */
|
||||||
|
if (info->need_stale_parent_threads_check)
|
||||||
|
{
|
||||||
|
int tgid = linux_proc_get_tgid (ti.ti_lid);
|
||||||
|
if (tgid != -1 && tgid != info->pid)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptid = ptid_build (info->pid, ti.ti_lid, 0);
|
||||||
tp = find_thread_pid (ptid);
|
tp = find_thread_pid (ptid);
|
||||||
if (tp == NULL || tp->private == NULL)
|
if (tp == NULL || tp->private == NULL)
|
||||||
attach_thread (ptid, th_p, &ti);
|
attach_thread (ptid, th_p, &ti);
|
||||||
@ -1479,6 +1500,27 @@ thread_db_get_ada_task_ptid (long lwp, long thread)
|
|||||||
return (thread_info->ptid);
|
return (thread_info->ptid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
thread_db_resume (struct target_ops *ops,
|
||||||
|
ptid_t ptid, int step, enum target_signal signo)
|
||||||
|
{
|
||||||
|
struct target_ops *beneath = find_target_beneath (ops);
|
||||||
|
struct thread_db_info *info;
|
||||||
|
|
||||||
|
if (ptid_equal (ptid, minus_one_ptid))
|
||||||
|
info = get_thread_db_info (GET_PID (inferior_ptid));
|
||||||
|
else
|
||||||
|
info = get_thread_db_info (GET_PID (ptid));
|
||||||
|
|
||||||
|
/* This workaround is only needed for child fork lwps stopped in a
|
||||||
|
PTRACE_O_TRACEFORK event. When the inferior is resumed, the
|
||||||
|
workaround can be disabled. */
|
||||||
|
if (info)
|
||||||
|
info->need_stale_parent_threads_check = 0;
|
||||||
|
|
||||||
|
beneath->to_resume (beneath, ptid, step, signo);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
init_thread_db_ops (void)
|
init_thread_db_ops (void)
|
||||||
{
|
{
|
||||||
@ -1487,6 +1529,7 @@ init_thread_db_ops (void)
|
|||||||
thread_db_ops.to_doc = "Threads and pthreads support.";
|
thread_db_ops.to_doc = "Threads and pthreads support.";
|
||||||
thread_db_ops.to_detach = thread_db_detach;
|
thread_db_ops.to_detach = thread_db_detach;
|
||||||
thread_db_ops.to_wait = thread_db_wait;
|
thread_db_ops.to_wait = thread_db_wait;
|
||||||
|
thread_db_ops.to_resume = thread_db_resume;
|
||||||
thread_db_ops.to_mourn_inferior = thread_db_mourn_inferior;
|
thread_db_ops.to_mourn_inferior = thread_db_mourn_inferior;
|
||||||
thread_db_ops.to_find_new_threads = thread_db_find_new_threads;
|
thread_db_ops.to_find_new_threads = thread_db_find_new_threads;
|
||||||
thread_db_ops.to_pid_to_str = thread_db_pid_to_str;
|
thread_db_ops.to_pid_to_str = thread_db_pid_to_str;
|
||||||
|
Reference in New Issue
Block a user