int thread_db_init (void) { struct process_info *proc = current_process (); /* FIXME drow/2004-10-16: This is the "overall process ID", which GNU/Linux calls tgid, "thread group ID". When we support attaching to threads, the original thread may not be the correct thread. We would have to get the process ID from /proc for NPTL. This isn't the only place in gdbserver that assumes that the first process in the list is the thread group leader. */ if (thread_db_load_search ()) { /* 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 GDBserver to get stuck in an infinite loop. As the kernel supports clone events and /proc/PID/task/ exists, then we already know about all threads in the process. When we need info out of thread_db on a given thread (e.g., for TLS), we'll use find_one_thread then. That uses thread_db entry points that do not walk libpthread's thread list, so should be safe, as well as more efficient. */ if (!linux_proc_task_list_dir_exists (pid_of (proc))) thread_db_find_new_threads (); thread_db_look_up_symbols (); return 1; } return 0; }
int thread_db_init () { int err; /* FIXME drow/2004-10-16: This is the "overall process ID", which GNU/Linux calls tgid, "thread group ID". When we support attaching to threads, the original thread may not be the correct thread. We would have to get the process ID from /proc for NPTL. For LinuxThreads we could do something similar: follow the chain of parent processes until we find the highest one we're attached to, and use its tgid. This isn't the only place in gdbserver that assumes that the first process in the list is the thread group leader. */ proc_handle.pid = ((struct inferior_list_entry *)current_inferior)->id; /* Allow new symbol lookups. */ all_symbols_looked_up = 0; err = td_ta_new (&proc_handle, &thread_agent); switch (err) { case TD_NOLIBTHREAD: /* No thread library was detected. */ return 0; case TD_OK: /* The thread library was detected. */ if (thread_db_enable_reporting () == 0) return 0; thread_db_find_new_threads (); thread_db_look_up_symbols (); all_symbols_looked_up = 1; return 1; default: warning ("error initializing thread_db library: %s", thread_db_err_str (err)); } return 0; }