aboutsummaryrefslogtreecommitdiff
path: root/gdb/gdbserver
diff options
context:
space:
mode:
authorKevin Buettner <kevinb@redhat.com>2017-04-04 16:17:05 -0700
committerKevin Buettner <kevinb@redhat.com>2017-09-21 11:49:47 -0700
commitf6327dcbf0bc91bb9d99e12232d2b1a2f959fce6 (patch)
tree82737d75423e02cbf0e2a93ff35bd7be7ed1539c /gdb/gdbserver
parent8629910955a751a93f2f12389ff1f497556cc260 (diff)
downloadgdb-f6327dcbf0bc91bb9d99e12232d2b1a2f959fce6.zip
gdb-f6327dcbf0bc91bb9d99e12232d2b1a2f959fce6.tar.gz
gdb-f6327dcbf0bc91bb9d99e12232d2b1a2f959fce6.tar.bz2
Add thread_handle_to_thread_info support for remote targets
This patch adds support to remote targets for converting a thread handle to a thread_info struct pointer. A thread handle is fetched via a "handle" attribute which has been added to the qXfer:threads:read query packet. An implementation is provided in gdbserver for targets using the Linux kernel. gdb/gdbserver/ChangeLog: * linux-low.h (struct lwp_info): Add new field, thread_handle. (thread_db_thread_handle): Declare. * linux-low.c (linux_target_ops): Initialize thread_handle. * server.c (handle_qxfer_threads_worker): Add support for "handle" attribute. * target.h (struct target_ops): Add new function pointer, thread_handle. (target_thread_handle): Define. * thread-db.c (find_one_thread, attach_thread): Set thread_handle field in lwp. (thread_db_thread_handle): New function. gdb/ChangeLog: * remote.c (vector): Include. (struct private_thread_info): Add field, thread_handle. (free_private_thread_info): Deallocate storage associated with thread handle. (get_private_info_thread): Initialize `thread_handle' field. (struct thread_item): Add field, thread_handle. (clear_threads_listing_context): Deallocate storage associated with thread handle. (start_thread): Add support for "handle" attribute. (thread_attributes): Add "handle". (remote_get_threads_with_qthreadinfo): Initialize thread_handle field. (remote_update_thread_list): Update thread_handle. (remote_thread_handle_to_thread_info): New function. (init_remote_ops): Initialize to_thread_handle_to_thread_info.
Diffstat (limited to 'gdb/gdbserver')
-rw-r--r--gdb/gdbserver/ChangeLog14
-rw-r--r--gdb/gdbserver/linux-low.c5
-rw-r--r--gdb/gdbserver/linux-low.h5
-rw-r--r--gdb/gdbserver/server.c10
-rw-r--r--gdb/gdbserver/target.h10
-rw-r--r--gdb/gdbserver/thread-db.c32
6 files changed, 76 insertions, 0 deletions
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog
index b075eb3..75d97f0 100644
--- a/gdb/gdbserver/ChangeLog
+++ b/gdb/gdbserver/ChangeLog
@@ -1,5 +1,19 @@
2017-09-21 Kevin Buettner <kevinb@redhat.com>
+ * linux-low.h (struct lwp_info): Add new field, thread_handle.
+ (thread_db_thread_handle): Declare.
+ * linux-low.c (linux_target_ops): Initialize thread_handle.
+ * server.c (handle_qxfer_threads_worker): Add support for
+ "handle" attribute.
+ * target.h (struct target_ops): Add new function pointer,
+ thread_handle.
+ (target_thread_handle): Define.
+ * thread-db.c (find_one_thread, attach_thread): Set thread_handle
+ field in lwp.
+ (thread_db_thread_handle): New function.
+
+2017-09-21 Kevin Buettner <kevinb@redhat.com>
+
* linux-low.c (handle_extended_wait): Call thread_db_notice_clone().
* linux-low.h (thread_db_notice_clone): Declare.
* thread-db.c (thread_db_notice_clone): New function.
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index a3f9ab9..c62dc19 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -7705,6 +7705,11 @@ static struct target_ops linux_target_ops = {
linux_supports_software_single_step,
linux_supports_catch_syscall,
linux_get_ipa_tdesc_idx,
+#if USE_THREAD_DB
+ thread_db_thread_handle,
+#else
+ NULL,
+#endif
};
#ifdef HAVE_LINUX_REGSETS
diff --git a/gdb/gdbserver/linux-low.h b/gdb/gdbserver/linux-low.h
index be27c92..85bb8ca 100644
--- a/gdb/gdbserver/linux-low.h
+++ b/gdb/gdbserver/linux-low.h
@@ -374,6 +374,9 @@ struct lwp_info
/* The thread handle, used for e.g. TLS access. Only valid if
THREAD_KNOWN is set. */
td_thrhandle_t th;
+
+ /* The pthread_t handle. */
+ thread_t thread_handle;
#endif
/* Arch-specific additions. */
@@ -416,4 +419,6 @@ int thread_db_look_up_one_symbol (const char *name, CORE_ADDR *addrp);
void thread_db_notice_clone (struct process_info *proc, ptid_t lwp);
+bool thread_db_thread_handle (ptid_t ptid, gdb_byte **handle, int *handle_len);
+
extern int have_ptrace_getregset;
diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
index a5743b5..f3eee31 100644
--- a/gdb/gdbserver/server.c
+++ b/gdb/gdbserver/server.c
@@ -1648,6 +1648,9 @@ handle_qxfer_threads_worker (struct inferior_list_entry *inf, void *arg)
int core = target_core_of_thread (ptid);
char core_s[21];
const char *name = target_thread_name (ptid);
+ int handle_len;
+ gdb_byte *handle;
+ bool handle_status = target_thread_handle (ptid, &handle, &handle_len);
write_ptid (ptid_s, ptid);
@@ -1662,6 +1665,13 @@ handle_qxfer_threads_worker (struct inferior_list_entry *inf, void *arg)
if (name != NULL)
buffer_xml_printf (buffer, " name=\"%s\"", name);
+ if (handle_status)
+ {
+ char *handle_s = (char *) alloca (handle_len * 2 + 1);
+ bin2hex (handle, handle_s, handle_len);
+ buffer_xml_printf (buffer, " handle=\"%s\"", handle_s);
+ }
+
buffer_xml_printf (buffer, "/>\n");
}
diff --git a/gdb/gdbserver/target.h b/gdb/gdbserver/target.h
index 91cbde1..0a3d1db 100644
--- a/gdb/gdbserver/target.h
+++ b/gdb/gdbserver/target.h
@@ -475,6 +475,11 @@ struct target_ops
/* Return tdesc index for IPA. */
int (*get_ipa_tdesc_idx) (void);
+
+ /* Thread ID to (numeric) thread handle: Return true on success and
+ false for failure. Return pointer to thread handle via HANDLE
+ and the handle's length via HANDLE_LEN. */
+ bool (*thread_handle) (ptid_t ptid, gdb_byte **handle, int *handle_len);
};
extern struct target_ops *the_target;
@@ -693,6 +698,11 @@ void done_accessing_memory (void);
(the_target->thread_name ? (*the_target->thread_name) (ptid) \
: NULL)
+#define target_thread_handle(ptid, handle, handle_len) \
+ (the_target->thread_handle ? (*the_target->thread_handle) \
+ (ptid, handle, handle_len) \
+ : false)
+
int read_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len);
int write_inferior_memory (CORE_ADDR memaddr, const unsigned char *myaddr,
diff --git a/gdb/gdbserver/thread-db.c b/gdb/gdbserver/thread-db.c
index 3d57f31..9156d89 100644
--- a/gdb/gdbserver/thread-db.c
+++ b/gdb/gdbserver/thread-db.c
@@ -200,6 +200,7 @@ find_one_thread (ptid_t ptid)
lwp->thread_known = 1;
lwp->th = th;
+ lwp->thread_handle = ti.ti_tid;
return 1;
}
@@ -231,6 +232,7 @@ attach_thread (const td_thrhandle_t *th_p, td_thrinfo_t *ti_p)
gdb_assert (lwp != NULL);
lwp->thread_known = 1;
lwp->th = *th_p;
+ lwp->thread_handle = ti_p->ti_tid;
return 1;
}
@@ -439,6 +441,36 @@ thread_db_get_tls_address (struct thread_info *thread, CORE_ADDR offset,
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;
+ struct thread_info *thread
+ = (struct thread_info *) find_inferior_id (&all_threads, 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->entry.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