#include "nat/gdb_thread_db.h"
#include "gdb_vecs.h"
#include "nat/linux-procfs.h"
+#include "common/scoped_restore.h"
#ifndef USE_LIBTHREAD_DB_DIRECTLY
#include <dlfcn.h>
}
#endif
+/* Get thread info about PTID, accessing memory via the current
+ thread. */
+
static int
find_one_thread (ptid_t ptid)
{
td_thrhandle_t th;
td_thrinfo_t ti;
td_err_e err;
- struct thread_info *inferior;
struct lwp_info *lwp;
struct thread_db *thread_db = current_process ()->priv->thread_db;
int lwpid = ptid_get_lwp (ptid);
- inferior = (struct thread_info *) find_inferior_id (&all_threads, ptid);
- lwp = get_thread_lwp (inferior);
+ thread_info *thread = find_thread_ptid (ptid);
+ lwp = get_thread_lwp (thread);
if (lwp->thread_known)
return 1;
lwp->thread_known = 1;
lwp->th = th;
+ lwp->thread_handle = ti.ti_tid;
return 1;
}
gdb_assert (lwp != NULL);
lwp->thread_known = 1;
lwp->th = *th_p;
+ lwp->thread_handle = ti_p->ti_tid;
return 1;
}
lwp = get_thread_lwp (thread);
if (!lwp->thread_known)
- find_one_thread (thread->entry.id);
+ find_one_thread (thread->id);
if (!lwp->thread_known)
return TD_NOTHR;
return err;
}
+/* See linux-low.h. */
+
+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;
+}
+
#ifdef USE_LIBTHREAD_DB_DIRECTLY
static int
/* See linux-low.h. */
void
-thread_db_notice_clone (struct process_info *proc, ptid_t ptid)
+thread_db_notice_clone (struct thread_info *parent_thr, ptid_t child_ptid)
{
- struct thread_db *thread_db = proc->priv->thread_db;
+ 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;
- if (!find_one_thread (ptid))
+ /* 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");
}