From patchwork Sun Sep 16 05:15:05 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Buettner X-Patchwork-Id: 29402 Received: (qmail 96543 invoked by alias); 16 Sep 2018 05:16:44 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 95944 invoked by uid 89); 16 Sep 2018 05:15:27 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=0.0 required=5.0 tests=TIME_LIMIT_EXCEEDED autolearn=unavailable version=3.3.2 spammy= X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sun, 16 Sep 2018 05:15:10 +0000 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id A6468308A943 for ; Sun, 16 Sep 2018 05:15:06 +0000 (UTC) Received: from pinnacle.lan (ovpn-117-176.phx2.redhat.com [10.3.117.176]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 799526C351 for ; Sun, 16 Sep 2018 05:15:06 +0000 (UTC) Date: Sat, 15 Sep 2018 22:15:05 -0700 From: Kevin Buettner To: gdb-patches@sourceware.org Subject: [PATCH 1/4] Add and implement thread_to_thread_handle Message-ID: <20180915221505.00d30923@pinnacle.lan> In-Reply-To: <20180915220836.7dda4a63@pinnacle.lan> References: <20180915220836.7dda4a63@pinnacle.lan> MIME-Version: 1.0 X-IsSubscribed: yes This patch adds a thread_to_thread_handle method to the target vector. It also implements this functionality for remote targets and linux native threads. gdb/ChangeLog: * gdbthread.h (thread_to_thread_handle): Declare. * thread.c (gdbtypes.h): Include. (thread_to_thread_handle): New function. * target.h (struct target_ops): Add thread_info_to_thread_handle. (target_thread_info_to_thread_handle): Declare. * target.c (target_thread_info_to_thread_handle): New function. * target-debug.h, target-delegates.c: Regenerate. * linux-thread-db.c (class thread_db_target): Add method thread_info_to_thread_handle. (thread_db_target::thread_info_to_thread_handle): Define. * remote.c (class remote_target): Add new method thread_info_to_thread_handle. (remote_target::thread_info_to_thread_handle): Define. --- gdb/gdbthread.h | 5 +++++ gdb/linux-thread-db.c | 19 +++++++++++++++++++ gdb/remote.c | 10 ++++++++++ gdb/target-debug.h | 2 ++ gdb/target-delegates.c | 28 ++++++++++++++++++++++++++++ gdb/target.c | 6 ++++++ gdb/target.h | 6 ++++++ gdb/thread.c | 22 ++++++++++++++++++++++ 8 files changed, 98 insertions(+) diff --git a/gdb/gdbthread.h b/gdb/gdbthread.h index 5950512..45a2259 100644 --- a/gdb/gdbthread.h +++ b/gdb/gdbthread.h @@ -459,6 +459,11 @@ struct thread_info *find_thread_by_handle (struct value *thread_handle, /* Finds the first thread of the specified inferior. */ extern struct thread_info *first_thread_of_inferior (inferior *inf); +/* Return thread handle of type TYPE given thread THR. Returns NULL if + there is no handle and throw an error if there is a size mismatch. */ +struct value *thread_to_thread_handle (struct thread_info *thr, + struct type *type); + /* Find thread parent. */ struct thread_info * thread_parent (struct thread_info *thread); diff --git a/gdb/linux-thread-db.c b/gdb/linux-thread-db.c index ad193d6..689e0f7 100644 --- a/gdb/linux-thread-db.c +++ b/gdb/linux-thread-db.c @@ -105,6 +105,7 @@ public: thread_info *thread_handle_to_thread_info (const gdb_byte *thread_handle, int handle_len, inferior *inf) override; + gdb::byte_vector thread_info_to_thread_handle (struct thread_info *) override; }; thread_db_target::thread_db_target () @@ -1695,6 +1696,24 @@ thread_db_target::thread_handle_to_thread_info (const gdb_byte *thread_handle, return NULL; } +/* Return the thread handle associated the thread_info pointer TP. */ + +gdb::byte_vector +thread_db_target::thread_info_to_thread_handle (struct thread_info *tp) +{ + thread_db_thread_info *priv = get_thread_db_thread_info (tp); + + if (priv == NULL) + return gdb::byte_vector (); + + int handle_size = sizeof (priv->tid); + gdb::byte_vector rv (handle_size); + + memcpy (rv.data (), &priv->tid, handle_size); + + return rv; +} + /* Get the address of the thread local variable in load module LM which is stored at OFFSET within the thread local storage for thread PTID. */ diff --git a/gdb/remote.c b/gdb/remote.c index 3b19da7..e46575d 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -499,6 +499,9 @@ public: int handle_len, inferior *inf) override; + gdb::byte_vector thread_info_to_thread_handle (struct thread_info *tp) + override; + void stop (ptid_t) override; void interrupt () override; @@ -14093,6 +14096,13 @@ remote_target::thread_handle_to_thread_info (const gdb_byte *thread_handle, return NULL; } +gdb::byte_vector +remote_target::thread_info_to_thread_handle (struct thread_info *tp) +{ + remote_thread_info *priv = get_remote_thread_info (tp); + return priv->thread_handle; +} + bool remote_target::can_async_p () { diff --git a/gdb/target-debug.h b/gdb/target-debug.h index 1e904b9..503482a 100644 --- a/gdb/target-debug.h +++ b/gdb/target-debug.h @@ -184,6 +184,8 @@ target_debug_do_print (host_address_to_string (X)) #define target_debug_print_thread_info_pp(X) \ target_debug_do_print (host_address_to_string (X)) +#define target_debug_print_gdb_byte_vector(X) \ + target_debug_do_print (host_address_to_string (X.data ())) static void target_debug_print_struct_target_waitstatus_p (struct target_waitstatus *status) diff --git a/gdb/target-delegates.c b/gdb/target-delegates.c index 03136df..76519f3 100644 --- a/gdb/target-delegates.c +++ b/gdb/target-delegates.c @@ -70,6 +70,7 @@ struct dummy_target : public target_ops const char *extra_thread_info (thread_info *arg0) override; const char *thread_name (thread_info *arg0) override; thread_info *thread_handle_to_thread_info (const gdb_byte *arg0, int arg1, inferior *arg2) override; + gdb::byte_vector thread_info_to_thread_handle (struct thread_info *arg0) override; void stop (ptid_t arg0) override; void interrupt () override; void pass_ctrlc () override; @@ -237,6 +238,7 @@ struct debug_target : public target_ops const char *extra_thread_info (thread_info *arg0) override; const char *thread_name (thread_info *arg0) override; thread_info *thread_handle_to_thread_info (const gdb_byte *arg0, int arg1, inferior *arg2) override; + gdb::byte_vector thread_info_to_thread_handle (struct thread_info *arg0) override; void stop (ptid_t arg0) override; void interrupt () override; void pass_ctrlc () override; @@ -1858,6 +1860,32 @@ debug_target::thread_handle_to_thread_info (const gdb_byte *arg0, int arg1, infe return result; } +gdb::byte_vector +target_ops::thread_info_to_thread_handle (struct thread_info *arg0) +{ + return this->beneath ()->thread_info_to_thread_handle (arg0); +} + +gdb::byte_vector +dummy_target::thread_info_to_thread_handle (struct thread_info *arg0) +{ + return gdb::byte_vector (); +} + +gdb::byte_vector +debug_target::thread_info_to_thread_handle (struct thread_info *arg0) +{ + gdb::byte_vector result; + fprintf_unfiltered (gdb_stdlog, "-> %s->thread_info_to_thread_handle (...)\n", this->beneath ()->shortname ()); + result = this->beneath ()->thread_info_to_thread_handle (arg0); + fprintf_unfiltered (gdb_stdlog, "<- %s->thread_info_to_thread_handle (", this->beneath ()->shortname ()); + target_debug_print_struct_thread_info_p (arg0); + fputs_unfiltered (") = ", gdb_stdlog); + target_debug_print_gdb_byte_vector (result); + fputs_unfiltered ("\n", gdb_stdlog); + return result; +} + void target_ops::stop (ptid_t arg0) { diff --git a/gdb/target.c b/gdb/target.c index 2d98954..8af2368 100644 --- a/gdb/target.c +++ b/gdb/target.c @@ -2147,6 +2147,12 @@ target_thread_handle_to_thread_info (const gdb_byte *thread_handle, handle_len, inf); } +gdb::byte_vector +target_thread_info_to_thread_handle (struct thread_info *tip) +{ + return current_top_target ()->thread_info_to_thread_handle (tip); +} + void target_resume (ptid_t ptid, int step, enum gdb_signal signal) { diff --git a/gdb/target.h b/gdb/target.h index a3000c8..3ee744b 100644 --- a/gdb/target.h +++ b/gdb/target.h @@ -658,6 +658,8 @@ struct target_ops int, inferior *inf) TARGET_DEFAULT_RETURN (NULL); + virtual gdb::byte_vector thread_info_to_thread_handle (struct thread_info *) + TARGET_DEFAULT_RETURN (gdb::byte_vector ()); virtual void stop (ptid_t) TARGET_DEFAULT_IGNORE (); virtual void interrupt () @@ -1863,6 +1865,10 @@ extern const char *target_thread_name (struct thread_info *); extern struct thread_info *target_thread_handle_to_thread_info (const gdb_byte *thread_handle, int handle_len, struct inferior *inf); +/* Given a thread, return the thread handle. */ +extern gdb::byte_vector target_thread_info_to_thread_handle + (struct thread_info *); + /* Attempts to find the pathname of the executable file that was run to create a specified process. diff --git a/gdb/thread.c b/gdb/thread.c index 6c17923..8ac8b97 100644 --- a/gdb/thread.c +++ b/gdb/thread.c @@ -46,6 +46,7 @@ #include #include "common/gdb_optional.h" #include "extension.h" +#include "gdbtypes.h" /* Definition of struct thread_info exported to gdbthread.h. */ @@ -532,6 +533,27 @@ find_thread_by_handle (struct value *thread_handle, struct inferior *inf) inf); } +/* See gdbthread.h. */ + +struct value * +thread_to_thread_handle (struct thread_info *thr, struct type *type) +{ + gdb::byte_vector hv = target_thread_info_to_thread_handle (thr); + + if (hv.size () == 0) + return NULL; + + check_typedef (type); + if (hv.size () != TYPE_LENGTH (type)) + error (_("Thread handle size mismatch: Expecting %d, got %zu instead"), + TYPE_LENGTH (type), hv.size ()); + + struct value *rv = allocate_value (type); + memcpy (value_contents_raw (rv), hv.data (), hv.size ()); + + return rv; +} + /* * Thread iterator function. *