/* libthread_db assisted debugging support, generic parts.
- Copyright (C) 1999-2015 Free Software Foundation, Inc.
+ Copyright (C) 1999-2016 Free Software Foundation, Inc.
This file is part of GDB.
created, thread IDs (usually, the result of pthread_self), and
thread-local variables.
- The libthread_db interface originates on Solaris, where it is
- both more powerful and more complicated. This implementation
- only works for LinuxThreads and NPTL, the two glibc threading
- libraries. It assumes that each thread is permanently assigned
- to a single light-weight process (LWP).
+ The libthread_db interface originates on Solaris, where it is both
+ more powerful and more complicated. This implementation only works
+ for NPTL, the glibc threading library. It assumes that each thread
+ is permanently assigned to a single light-weight process (LWP). At
+ some point it also supported the older LinuxThreads library, but it
+ no longer does.
libthread_db-specific information is stored in the "private" field
of struct thread_info. When the field is NULL we do not yet have
ptid = ptid_build (info->pid, ti.ti_lid, 0);
tp = find_thread_ptid (ptid);
if (tp == NULL || tp->priv == NULL)
- thread_from_lwp (ptid);
+ record_thread (info, tp, ptid, th_p, &ti);
return 0;
}
thread_db_find_new_threads_2 (ptid, 0);
}
-static int
-update_thread_core (struct lwp_info *info, void *closure)
-{
- info->core = linux_common_core_of_thread (info->ptid);
- return 0;
-}
-
-/* Update the thread list using td_ta_thr_iter. */
+/* Implement the to_update_thread_list target method for this
+ target. */
static void
-thread_db_update_thread_list_td_ta_thr_iter (struct target_ops *ops)
+thread_db_update_thread_list (struct target_ops *ops)
{
struct thread_db_info *info;
struct inferior *inf;
if (thread == NULL || thread->executing)
continue;
+ /* It's best to avoid td_ta_thr_iter if possible. That walks
+ data structures in the inferior's address space that may be
+ corrupted, or, if the target is running, the list may change
+ while we walk it. In the latter case, it's possible that a
+ thread exits just at the exact time that causes GDB to get
+ stuck in an infinite loop. To avoid pausing all threads
+ whenever the core wants to refresh the thread list, we
+ instead use thread_from_lwp immediately when we see an LWP
+ stop. That uses thread_db entry points that do not walk
+ libpthread's thread list, so should be safe, as well as more
+ efficient. */
+ if (target_has_execution_1 (thread->ptid))
+ continue;
+
thread_db_find_new_threads_1 (thread->ptid);
}
-}
-/* Implement the to_update_thread_list target method for this
- target. */
-
-static void
-thread_db_update_thread_list (struct target_ops *ops)
-{
- /* It's best to avoid td_ta_thr_iter if possible. That walks data
- structures in the inferior's address space that may be corrupted,
- or, if the target is running, the list may change while we walk
- it. In the latter case, it's possible that a thread exits just
- at the exact time that causes GDB to get stuck in an infinite
- loop. To avoid pausing all threads whenever the core wants to
- refresh the thread list, use thread_from_lwp immediately when we
- see an LWP stop. That uses thread_db entry points that do not
- walk libpthread's thread list, so should be safe, as well as
- more efficient. */
- if (target_has_execution)
- ops->beneath->to_update_thread_list (ops->beneath);
- else
- thread_db_update_thread_list_td_ta_thr_iter (ops);
-
- if (target_has_execution)
- iterate_over_lwps (minus_one_ptid /* iterate over all */,
- update_thread_core, NULL);
+ /* Give the beneath target a chance to do extra processing. */
+ ops->beneath->to_update_thread_list (ops->beneath);
}
static char *
/* Defer loading of libthread_db.so until inferior is running.
This allows gdb to load correct libthread_db for a given
- executable -- there could be mutiple versions of glibc,
- compiled with LinuxThreads or NPTL, and until there is
- a running inferior, we can't tell which libthread_db is
- the correct one to load. */
+ executable -- there could be multiple versions of glibc,
+ and until there is a running inferior, we can't tell which
+ libthread_db is the correct one to load. */
libthread_db_search_path = xstrdup (LIBTHREAD_DB_SEARCH_PATH);