diff options
author | Kevin Buettner <kevinb@redhat.com> | 2017-04-04 16:17:05 -0700 |
---|---|---|
committer | Kevin Buettner <kevinb@redhat.com> | 2017-09-21 11:49:47 -0700 |
commit | f6327dcbf0bc91bb9d99e12232d2b1a2f959fce6 (patch) | |
tree | 82737d75423e02cbf0e2a93ff35bd7be7ed1539c /gdb/gdbserver | |
parent | 8629910955a751a93f2f12389ff1f497556cc260 (diff) | |
download | gdb-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/ChangeLog | 14 | ||||
-rw-r--r-- | gdb/gdbserver/linux-low.c | 5 | ||||
-rw-r--r-- | gdb/gdbserver/linux-low.h | 5 | ||||
-rw-r--r-- | gdb/gdbserver/server.c | 10 | ||||
-rw-r--r-- | gdb/gdbserver/target.h | 10 | ||||
-rw-r--r-- | gdb/gdbserver/thread-db.c | 32 |
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 |