static int thread_db_create_event (CORE_ADDR where) { td_event_msg_t msg; td_err_e err; struct lwp_info *lwp; struct thread_db *thread_db = current_process ()->priv->thread_db; gdb_assert (thread_db->td_ta_event_getmsg_p != NULL); if (debug_threads) debug_printf ("Thread creation event.\n"); /* FIXME: This assumes we don't get another event. In the LinuxThreads implementation, this is safe, because all events come from the manager thread (except for its own creation, of course). */ err = thread_db->td_ta_event_getmsg_p (thread_db->thread_agent, &msg); if (err != TD_OK) fprintf (stderr, "thread getmsg err: %s\n", thread_db_err_str (err)); /* If we do not know about the main thread yet, this would be a good time to find it. We need to do this to pick up the main thread before any newly created threads. */ lwp = get_thread_lwp (current_thread); if (lwp->thread_known == 0) find_one_thread (current_thread->entry.id); /* msg.event == TD_EVENT_CREATE */ find_new_threads_callback (msg.th_p, NULL); return 0; }
bool thread_db_thread_handle (ptid_t ptid, gdb_byte **handle, int *handle_len) { struct thread_db *thread_db; struct lwp_info *lwp; thread_info *thread = find_thread_ptid (ptid); if (thread == NULL) return false; thread_db = get_thread_process (thread)->priv->thread_db; if (thread_db == NULL) return false; lwp = get_thread_lwp (thread); if (!lwp->thread_known && !find_one_thread (thread->id)) return false; gdb_assert (lwp->thread_known); *handle = (gdb_byte *) &lwp->thread_handle; *handle_len = sizeof (lwp->thread_handle); return true; }
static void thread_db_find_new_threads (void) { td_err_e err; ptid_t ptid = current_ptid; struct thread_db *thread_db = current_process ()->priv->thread_db; int loop, iteration; /* This function is only called when we first initialize thread_db. First locate the initial thread. If it is not ready for debugging yet, then stop. */ if (find_one_thread (ptid) == 0) return; /* Require 4 successive iterations which do not find any new threads. The 4 is a heuristic: there is an inherent race here, and I have seen that 2 iterations in a row are not always sufficient to "capture" all threads. */ for (loop = 0, iteration = 0; loop < 4; ++loop, ++iteration) { int new_thread_count = 0; /* Iterate over all user-space threads to discover new threads. */ err = thread_db->td_ta_thr_iter_p (thread_db->thread_agent, find_new_threads_callback, &new_thread_count, TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY, TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS); if (debug_threads) debug_printf ("Found %d threads in iteration %d.\n", new_thread_count, iteration); if (new_thread_count != 0) { /* Found new threads. Restart iteration from beginning. */ loop = -1; } } if (err != TD_OK) error ("Cannot find new threads: %s", thread_db_err_str (err)); }
void thread_db_notice_clone (struct thread_info *parent_thr, ptid_t child_ptid) { process_info *parent_proc = get_thread_process (parent_thr); struct thread_db *thread_db = parent_proc->priv->thread_db; /* If the thread layer isn't initialized, return. It may just be that the program uses clone, but does not use libthread_db. */ if (thread_db == NULL || !thread_db->all_symbols_looked_up) return; /* find_one_thread calls into libthread_db which accesses memory via the current thread. Temporarily switch to a thread we know is stopped. */ scoped_restore restore_current_thread = make_scoped_restore (¤t_thread, parent_thr); if (!find_one_thread (child_ptid)) warning ("Cannot find thread after clone.\n"); }
int thread_db_get_tls_address (struct thread_info *thread, CORE_ADDR offset, CORE_ADDR load_module, CORE_ADDR *address) { psaddr_t addr; td_err_e err; struct lwp_info *lwp; struct thread_info *saved_thread; struct process_info *proc; struct thread_db *thread_db; proc = get_thread_process (thread); thread_db = proc->priv->thread_db; /* If the thread layer is not (yet) initialized, fail. */ if (thread_db == NULL || !thread_db->all_symbols_looked_up) return TD_ERR; /* If td_thr_tls_get_addr is missing rather do not expect td_thr_tlsbase could work. */ if (thread_db->td_thr_tls_get_addr_p == NULL || (load_module == 0 && thread_db->td_thr_tlsbase_p == NULL)) return -1; lwp = get_thread_lwp (thread); if (!lwp->thread_known) find_one_thread (thread->entry.id); if (!lwp->thread_known) return TD_NOTHR; saved_thread = current_thread; current_thread = thread; if (load_module != 0) { /* Note the cast through uintptr_t: this interface only works if a target address fits in a psaddr_t, which is a host pointer. So a 32-bit debugger can not access 64-bit TLS through this. */ err = thread_db->td_thr_tls_get_addr_p (&lwp->th, (psaddr_t) (uintptr_t) load_module, offset, &addr); } else { /* This code path handles the case of -static -pthread executables: https://sourceware.org/ml/libc-help/2014-03/msg00024.html For older GNU libc r_debug.r_map is NULL. For GNU libc after PR libc/16831 due to GDB PR threads/16954 LOAD_MODULE is also NULL. The constant number 1 depends on GNU __libc_setup_tls initialization of l_tls_modid to 1. */ err = thread_db->td_thr_tlsbase_p (&lwp->th, 1, &addr); addr = (char *) addr + offset; } current_thread = saved_thread; if (err == TD_OK) { *address = (CORE_ADDR) (uintptr_t) addr; return 0; } else return err; }