public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v4 0/6] Add python method gdb.InferiorThread.handle
@ 2019-04-04 16:59 Kevin Buettner
  2019-04-04 16:59 ` [PATCH v4 1/6] Introduce target_ops method thread_info_to_thread_handle Kevin Buettner
                   ` (6 more replies)
  0 siblings, 7 replies; 10+ messages in thread
From: Kevin Buettner @ 2019-04-04 16:59 UTC (permalink / raw)
  To: gdb-patches; +Cc: Kevin Buettner

This six part series adds a python method named "handle" which is used
to obtain the thread handle from a thread object.

It will eventually be used as part of the implementation of the
"thread parent" operation for the OpenMP work that I've been doing.

While thread handles are normally opaque, for my OpenMP work, it's
become necessary to convert a handle to a form upon which arithmetic
may be performed.  Via some simple arithmetic manipulations, it's
possible to find the handle associated with a GOMP thread.  If you want
details on this, see:

https://www.sourceware.org/ml/gdb-patches/2018-09/msg00719.html

This is version 3 of a series that I first posted in Sept, 2018.

In v1, InferiorThread.thread_handle was passed a type and returned
a gdb.Value object representing the handle (of the type passed in).

In v2, InferiorThread.thread_handle is a nullary method.  It returns
the thread handle represented as a Python bytes object.  If it's
necessary to pierce the opacity of this object, as it is for my use
case, the two argument form of the gdb.Value constructor may be used
to make an object of some suitable type.

In v3, the name has been changed to "handle" instead of
"thread_handle" at the suggestion of Tom Tromey.  I've also fixed a
few other small problems identified by Tom.  Also, in order to stay
consistent with the new naming, "thread_from_thread_handle", an
existing python method, has been renamed to "thread_from_handle".  The
old name may still be used, but is considered deprecated.

In v4, this version, patches 1 and 2 have been revised slightly to
address some additional problems found by Tom Tromey.  Patches 3-6
are unchanged, but are included for completeness.

Kevin


 gdb/doc/python.texi                       | 17 +++++-
 gdb/gdbthread.h                           |  4 +-
 gdb/linux-thread-db.c                     | 19 +++++++
 gdb/python/py-inferior.c                  | 37 ++++++++++--
 gdb/python/py-infthread.c                 | 34 ++++++++++++
 gdb/remote.c                              | 10 ++++
 gdb/target-debug.h                        |  2 +
 gdb/target-delegates.c                    | 28 ++++++++++
 gdb/target.c                              |  8 +++
 gdb/target.h                              |  9 +++
 gdb/testsuite/gdb.python/py-thrhandle.exp | 68 +++++++++++++++++------
 gdb/thread.c                              | 10 ++--
 12 files changed, 215 insertions(+), 31 deletions(-)

-- 
2.20.1

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v4 1/6] Introduce target_ops method thread_info_to_thread_handle
  2019-04-04 16:59 [PATCH v4 0/6] Add python method gdb.InferiorThread.handle Kevin Buettner
@ 2019-04-04 16:59 ` Kevin Buettner
  2019-04-04 17:00 ` [PATCH v4 4/6] Tests for gdb.InferiorThread.handle Kevin Buettner
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Kevin Buettner @ 2019-04-04 16:59 UTC (permalink / raw)
  To: gdb-patches; +Cc: Kevin Buettner

This patch adds a thread_info_to_thread_handle method to the target_ops
struct.  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_debug_print_gdb_byte_vector): Define.
	* 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/linux-thread-db.c  | 19 +++++++++++++++++++
 gdb/remote.c           | 10 ++++++++++
 gdb/target-debug.h     |  2 ++
 gdb/target-delegates.c | 28 ++++++++++++++++++++++++++++
 gdb/target.c           |  8 ++++++++
 gdb/target.h           |  9 +++++++++
 6 files changed, 76 insertions(+)

diff --git a/gdb/linux-thread-db.c b/gdb/linux-thread-db.c
index a735807f58..37b67d9147 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;
 };
 
 static char *libthread_db_search_path;
@@ -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 657a4a25ca..cda456f9d1 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -485,6 +485,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;
@@ -14003,6 +14006,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 bef8a7f330..aa2adcec3d 100644
--- a/gdb/target-debug.h
+++ b/gdb/target-debug.h
@@ -186,6 +186,8 @@
   target_debug_do_print (host_address_to_string (X))
 #define target_debug_print_std_string(X) \
   target_debug_do_print ((X).c_str ())
+#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 3654f02e63..cfc0ce06e9 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;
@@ -1854,6 +1856,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 6c05b6b83e..6097993272 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -2098,6 +2098,14 @@ target_thread_handle_to_thread_info (const gdb_byte *thread_handle,
 						     handle_len, inf);
 }
 
+/* See target.h.  */
+
+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 4f7a43e1a8..9078a42001 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -659,6 +659,9 @@ struct target_ops
 						       int,
 						       inferior *inf)
       TARGET_DEFAULT_RETURN (NULL);
+    /* See target_thread_info_to_thread_handle.  */
+    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 ()
@@ -1851,6 +1854,12 @@ 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, a target-specific sequence of
+   bytes which serves as a thread identifier within the program being
+   debugged.  */
+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.
 
-- 
2.20.1

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v4 5/6] Documentation for python method InferiorThread.handle
  2019-04-04 16:59 [PATCH v4 0/6] Add python method gdb.InferiorThread.handle Kevin Buettner
                   ` (4 preceding siblings ...)
  2019-04-04 17:00 ` [PATCH v4 6/6] Rename python function thread_from_thread_handle to thread_from_handle Kevin Buettner
@ 2019-04-04 17:00 ` Kevin Buettner
  2019-04-08 20:30 ` [PATCH v4 0/6] Add python method gdb.InferiorThread.handle Tom Tromey
  6 siblings, 0 replies; 10+ messages in thread
From: Kevin Buettner @ 2019-04-04 17:00 UTC (permalink / raw)
  To: gdb-patches; +Cc: Kevin Buettner

gdb/doc/ChangeLog:

	* python.texi (Threads In Python): Add description for method
	InferiorThread.handle.
---
 gdb/doc/python.texi | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi
index 67165ac3ba..6a967ec26c 100644
--- a/gdb/doc/python.texi
+++ b/gdb/doc/python.texi
@@ -3334,6 +3334,14 @@ Return a Boolean indicating whether the thread is running.
 Return a Boolean indicating whether the thread is exited.
 @end defun
 
+@defun InferiorThread.handle ()
+Return the thread object's handle, represented as a Python @code{bytes}
+object.  A @code{gdb.Value} representation of the handle may be
+constructed via @code{gdb.Value(bufobj, type)} where @var{bufobj} is
+the Python @code{bytes} representation of the handle and @var{type} is
+a @code{gdb.Type} for the handle type.
+@end defun
+
 @node Recordings In Python
 @subsubsection Recordings In Python
 @cindex recordings in python
-- 
2.20.1

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v4 2/6] Add python method InferiorThread.handle
  2019-04-04 16:59 [PATCH v4 0/6] Add python method gdb.InferiorThread.handle Kevin Buettner
                   ` (2 preceding siblings ...)
  2019-04-04 17:00 ` [PATCH v4 3/6] Support buffer objects as handles in Inferior.thread_from_thread_handle() Kevin Buettner
@ 2019-04-04 17:00 ` Kevin Buettner
  2019-04-04 17:00 ` [PATCH v4 6/6] Rename python function thread_from_thread_handle to thread_from_handle Kevin Buettner
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Kevin Buettner @ 2019-04-04 17:00 UTC (permalink / raw)
  To: gdb-patches; +Cc: Kevin Buettner

gdb/ChangeLog:

	* python/py-infthread.c (thpy_thread_handle): New function.
	(thread_object_methods): Register thpy_thread_handle.
---
 gdb/python/py-infthread.c | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/gdb/python/py-infthread.c b/gdb/python/py-infthread.c
index bf90d08ae6..1d201b9b35 100644
--- a/gdb/python/py-infthread.c
+++ b/gdb/python/py-infthread.c
@@ -257,6 +257,37 @@ thpy_is_valid (PyObject *self, PyObject *args)
   Py_RETURN_TRUE;
 }
 
+/* Implementation of gdb.InferiorThread.handle (self) -> handle. */
+
+static PyObject *
+thpy_thread_handle (PyObject *self, PyObject *args)
+{
+  thread_object *thread_obj = (thread_object *) self;
+  THPY_REQUIRE_VALID (thread_obj);
+
+  gdb::byte_vector hv;
+  
+  TRY
+    {
+      hv = target_thread_info_to_thread_handle (thread_obj->thread);
+    }
+  CATCH (ex, RETURN_MASK_ALL)
+    {
+      GDB_PY_HANDLE_EXCEPTION (ex);
+    }
+  END_CATCH
+
+  if (hv.size () == 0)
+    {
+      PyErr_SetString (PyExc_RuntimeError, _("Thread handle not found."));
+      return NULL;
+    }
+
+  PyObject *object = PyBytes_FromStringAndSize ((const char *) hv.data (),
+				                hv.size());
+  return object;
+}
+
 /* Return a reference to a new Python object representing a ptid_t.
    The object is a tuple containing (pid, lwp, tid). */
 PyObject *
@@ -336,6 +367,9 @@ Return whether the thread is running." },
   { "is_exited", thpy_is_exited, METH_NOARGS,
     "is_exited () -> Boolean\n\
 Return whether the thread is exited." },
+  { "handle", thpy_thread_handle, METH_NOARGS,
+    "handle  () -> handle\n\
+Return thread library specific handle for thread." },
 
   { NULL }
 };
-- 
2.20.1

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v4 6/6] Rename python function thread_from_thread_handle to thread_from_handle
  2019-04-04 16:59 [PATCH v4 0/6] Add python method gdb.InferiorThread.handle Kevin Buettner
                   ` (3 preceding siblings ...)
  2019-04-04 17:00 ` [PATCH v4 2/6] Add python method InferiorThread.handle Kevin Buettner
@ 2019-04-04 17:00 ` Kevin Buettner
  2019-04-04 17:00 ` [PATCH v4 5/6] Documentation for python method InferiorThread.handle Kevin Buettner
  2019-04-08 20:30 ` [PATCH v4 0/6] Add python method gdb.InferiorThread.handle Tom Tromey
  6 siblings, 0 replies; 10+ messages in thread
From: Kevin Buettner @ 2019-04-04 17:00 UTC (permalink / raw)
  To: gdb-patches; +Cc: Kevin Buettner

This renaming was done to stay consistent with the naming of the new
gdb.InferiorThread.handle method.  I had initially named it "thread_handle"
but Tom Tromey suggested just "handle".

The old name (thread_from_thread_handle) still works, but is marked as
deprecated in comments in the code as well as in the documentation.

I have some code which uses these functions.  I very much like the
brevity of the new names.

gdb/doc/ChangeLog:

	* python.texi (Inferiors In Python): Rename
	Inferior.thread_from_thread_handle to Inferior.thread_from_handle.
	Add note about the former being deprecated.

gdb/ChangeLog:

	* python/py-inferior.c (infpy_thread_from_thread_handle):
	Adjust comments to reflect renaming of thread_from_thread_handle
	to thread_from_handle.  Adjust keywords.  Fix type error message.
	(inferior_object_methods): Add thread_from_handle.  Retain
	thread_from_thread_handle, but mark it as deprecated.

testsuite/ChangeLog:

	* gdb.python/py-thrhandle.exp: Adjust tests to call
	thread_from_handle instead of thread_from_thread_handle.
---
 gdb/doc/python.texi                       |  9 +++++--
 gdb/python/py-inferior.c                  | 12 ++++++---
 gdb/testsuite/gdb.python/py-thrhandle.exp | 30 +++++++++++------------
 3 files changed, 31 insertions(+), 20 deletions(-)

diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi
index 6a967ec26c..36947de30b 100644
--- a/gdb/doc/python.texi
+++ b/gdb/doc/python.texi
@@ -3000,11 +3000,16 @@ containing the address where the pattern was found, or @code{None} if
 the pattern could not be found.
 @end defun
 
+@findex Inferior.thread_from_handle
 @findex Inferior.thread_from_thread_handle
-@defun Inferior.thread_from_thread_handle (thread_handle)
-Return the thread object corresponding to @var{thread_handle}, a thread
+@defun Inferior.thread_from_handle (handle)
+Return the thread object corresponding to @var{handle}, a thread
 library specific data structure such as @code{pthread_t} for pthreads
 library implementations.
+
+The function @code{Inferior.thread_from_thread_handle} provides
+the same functionality, but use of @code{Inferior.thread_from_thread_handle}
+is deprecated.
 @end defun
 
 @node Events In Python
diff --git a/gdb/python/py-inferior.c b/gdb/python/py-inferior.c
index 7129815b21..36c9a65049 100644
--- a/gdb/python/py-inferior.c
+++ b/gdb/python/py-inferior.c
@@ -759,7 +759,7 @@ infpy_is_valid (PyObject *self, PyObject *args)
   Py_RETURN_TRUE;
 }
 
-/* Implementation of gdb.Inferior.thread_from_thread_handle (self, handle)
+/* Implementation of gdb.Inferior.thread_from_handle (self, handle)
                         ->  gdb.InferiorThread.  */
 
 static PyObject *
@@ -767,7 +767,7 @@ infpy_thread_from_thread_handle (PyObject *self, PyObject *args, PyObject *kw)
 {
   PyObject *handle_obj;
   inferior_object *inf_obj = (inferior_object *) self;
-  static const char *keywords[] = { "thread_handle", NULL };
+  static const char *keywords[] = { "handle", NULL };
 
   INFPY_REQUIRE_VALID (inf_obj);
 
@@ -795,7 +795,7 @@ infpy_thread_from_thread_handle (PyObject *self, PyObject *args, PyObject *kw)
   else
     {
       PyErr_SetString (PyExc_TypeError,
-		       _("Argument 'handle_obj' must be a thread handle object."));
+		       _("Argument 'handle' must be a thread handle object."));
 
       return NULL;
     }
@@ -961,9 +961,15 @@ Write the given buffer object to the inferior's memory." },
     METH_VARARGS | METH_KEYWORDS,
     "search_memory (address, length, pattern) -> long\n\
 Return a long with the address of a match, or None." },
+  /* thread_from_thread_handle is deprecated.  */
   { "thread_from_thread_handle", (PyCFunction) infpy_thread_from_thread_handle,
     METH_VARARGS | METH_KEYWORDS,
     "thread_from_thread_handle (handle) -> gdb.InferiorThread.\n\
+Return thread object corresponding to thread handle.\n\
+This method is deprecated - use thread_from_handle instead." },
+  { "thread_from_handle", (PyCFunction) infpy_thread_from_thread_handle,
+    METH_VARARGS | METH_KEYWORDS,
+    "thread_from_handle (handle) -> gdb.InferiorThread.\n\
 Return thread object corresponding to thread handle." },
   { "architecture", (PyCFunction) infpy_architecture, METH_NOARGS,
     "architecture () -> gdb.Architecture\n\
diff --git a/gdb/testsuite/gdb.python/py-thrhandle.exp b/gdb/testsuite/gdb.python/py-thrhandle.exp
index 57b97faa18..19c690be14 100644
--- a/gdb/testsuite/gdb.python/py-thrhandle.exp
+++ b/gdb/testsuite/gdb.python/py-thrhandle.exp
@@ -16,7 +16,7 @@
 # Please email any bugs, comments, and/or additions to this file to:
 # bug-gdb@gnu.org
 
-# This file verifies that methods Inferior.thread_from_thread_handle
+# This file verifies that methods Inferior.thread_from_handle
 # and InferiorThread.handle work as expected.
 
 load_lib gdb-python.exp
@@ -67,44 +67,44 @@ gdb_test "info threads"  \
 	{.*[\r\n]+\* +([0-9]+) +Thread[^\r\n]* do_something \(n=\1\) at.*}
 
 # Check for expected results when passing a valid thread handle to
-# thread_from_thread_handle().
+# thread_from_handle().
 
-gdb_test "python print(gdb.selected_inferior().thread_from_thread_handle(gdb.parse_and_eval('thrs\[0\]')).num)" \
+gdb_test "python print(gdb.selected_inferior().thread_from_handle(gdb.parse_and_eval('thrs\[0\]')).num)" \
 	"1" "print thread id for thrs\[0\]"
 
-gdb_test "python print(gdb.selected_inferior().thread_from_thread_handle(gdb.parse_and_eval('thrs\[1\]')).num)" \
+gdb_test "python print(gdb.selected_inferior().thread_from_handle(gdb.parse_and_eval('thrs\[1\]')).num)" \
 	"2" "print thread id for thrs\[1\]"
 
-gdb_test "python print(gdb.selected_inferior().thread_from_thread_handle(gdb.parse_and_eval('thrs\[2\]')).num)" \
+gdb_test "python print(gdb.selected_inferior().thread_from_handle(gdb.parse_and_eval('thrs\[2\]')).num)" \
 	"3" "print thread id for thrs\[2\]"
 
 # Objects which are of the correct size, but which are bogus thread
 # handles should return None.  For the first test (using thrs[3]), we
 # use 0.  For the second (thrs[4]), we use an unlikely bit pattern.
 
-gdb_test "python print(gdb.selected_inferior().thread_from_thread_handle(gdb.parse_and_eval('thrs\[3\]')))" \
+gdb_test "python print(gdb.selected_inferior().thread_from_handle(gdb.parse_and_eval('thrs\[3\]')))" \
 	"None" "print thread for bogus handle thrs\[3\]"
 
-gdb_test "python print(gdb.selected_inferior().thread_from_thread_handle(gdb.parse_and_eval('thrs\[4\]')))" \
+gdb_test "python print(gdb.selected_inferior().thread_from_handle(gdb.parse_and_eval('thrs\[4\]')))" \
 	"None" "print thread for bogus handle thrs\[4\]"
 
 # We should see an exception when passing an object of the wrong type.
 
-gdb_test "python print(gdb.selected_inferior().thread_from_thread_handle(gdb.lookup_symbol('main')))" \
-         ".*TypeError: Argument 'handle_obj' must be a thread handle object.*" \
-	 "TypeError when passing a symbol object to thread_from_thread_handle"
+gdb_test "python print(gdb.selected_inferior().thread_from_handle(gdb.lookup_symbol('main')))" \
+         ".*TypeError: Argument 'handle' must be a thread handle object.*" \
+	 "TypeError when passing a symbol object to thread_from_handle"
 
 # We should see an exception when passing too large of an object.
 
-gdb_test "python print(gdb.selected_inferior().thread_from_thread_handle(gdb.parse_and_eval('thrs')))" \
+gdb_test "python print(gdb.selected_inferior().thread_from_handle(gdb.parse_and_eval('thrs')))" \
          ".*Thread handle size mismatch.*" \
-	 "Pass overly large object to thread_from_thread_handle"
+	 "Pass overly large object to thread_from_handle"
 
 # We should see an exception when passing too small of an object.
 
-gdb_test "python print(gdb.selected_inferior().thread_from_thread_handle(gdb.parse_and_eval('\"S\"')))" \
+gdb_test "python print(gdb.selected_inferior().thread_from_handle(gdb.parse_and_eval('\"S\"')))" \
          ".*Thread handle size mismatch.*" \
-	 "Pass too small of an object to thread_from_thread_handle"
+	 "Pass too small of an object to thread_from_handle"
 
 # Test the thread_handle method
 
@@ -121,7 +121,7 @@ foreach thrN {0 1 2} {
 	    1
 
 	gdb_py_test_silent_cmd \
-	    "python hand_bytes = inf.thread_from_thread_handle(hand).handle()" \
+	    "python hand_bytes = inf.thread_from_handle(hand).handle()" \
 	    "fetch thread handle from thread" \
 	    1
 
-- 
2.20.1

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v4 4/6] Tests for gdb.InferiorThread.handle
  2019-04-04 16:59 [PATCH v4 0/6] Add python method gdb.InferiorThread.handle Kevin Buettner
  2019-04-04 16:59 ` [PATCH v4 1/6] Introduce target_ops method thread_info_to_thread_handle Kevin Buettner
@ 2019-04-04 17:00 ` Kevin Buettner
  2019-05-03  0:04   ` New FAILs (gdb.python/py-thrhandle.exp) on unix/-m32 (was: Re: [PATCH v4 4/6] Tests for gdb.InferiorThread.handle) Sergio Durigan Junior
  2019-04-04 17:00 ` [PATCH v4 3/6] Support buffer objects as handles in Inferior.thread_from_thread_handle() Kevin Buettner
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 10+ messages in thread
From: Kevin Buettner @ 2019-04-04 17:00 UTC (permalink / raw)
  To: gdb-patches; +Cc: Kevin Buettner

gdb/testsuite/ChangeLog:

	* gdb.python/py-thrhandle.exp: Add tests for
	gdb.InferiorThread.handle.
---
 gdb/testsuite/gdb.python/py-thrhandle.exp | 42 +++++++++++++++++++++--
 1 file changed, 39 insertions(+), 3 deletions(-)

diff --git a/gdb/testsuite/gdb.python/py-thrhandle.exp b/gdb/testsuite/gdb.python/py-thrhandle.exp
index 2c905b444f..57b97faa18 100644
--- a/gdb/testsuite/gdb.python/py-thrhandle.exp
+++ b/gdb/testsuite/gdb.python/py-thrhandle.exp
@@ -16,11 +16,12 @@
 # Please email any bugs, comments, and/or additions to this file to:
 # bug-gdb@gnu.org
 
-# This file verifies that gdb.Inferior.thread_from_thread_handle works
-# as expected.
+# This file verifies that methods Inferior.thread_from_thread_handle
+# and InferiorThread.handle work as expected.
 
-standard_testfile
+load_lib gdb-python.exp
 
+standard_testfile
 
 if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable debug] != "" } {
     return -1
@@ -104,3 +105,38 @@ gdb_test "python print(gdb.selected_inferior().thread_from_thread_handle(gdb.par
 gdb_test "python print(gdb.selected_inferior().thread_from_thread_handle(gdb.parse_and_eval('\"S\"')))" \
          ".*Thread handle size mismatch.*" \
 	 "Pass too small of an object to thread_from_thread_handle"
+
+# Test the thread_handle method
+
+gdb_py_test_silent_cmd "python tp=gdb.lookup_type('pthread_t')" \
+		       "Get pthread_t type" 0
+gdb_py_test_silent_cmd "python inf=gdb.selected_inferior()" "Get inferior" 0
+
+foreach thrN {0 1 2} {
+    with_test_prefix "thread $thrN" {
+
+	gdb_py_test_silent_cmd \
+	    "python hand = gdb.parse_and_eval('thrs\[$thrN\]')" \
+	    "fetch thread handle from inferior" \
+	    1
+
+	gdb_py_test_silent_cmd \
+	    "python hand_bytes = inf.thread_from_thread_handle(hand).handle()" \
+	    "fetch thread handle from thread" \
+	    1
+
+
+	# It'd be nice to be able to use this comparison expression:
+	#
+	#    hand == hand_bytes
+	#
+	# But this won't work because hand is a gdb.Value and hand_bytes
+	# is a Python bytes object.  Therefore, we convert the bytes
+	# object into a gdb.value by calling the two argument form of
+	# its constructor.
+
+        gdb_test "python print(gdb.Value(hand_bytes, tp) == hand)" \
+	         "True" \
+	         "verify that handles are the same"
+    }
+}
-- 
2.20.1

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v4 3/6] Support buffer objects as handles in Inferior.thread_from_thread_handle()
  2019-04-04 16:59 [PATCH v4 0/6] Add python method gdb.InferiorThread.handle Kevin Buettner
  2019-04-04 16:59 ` [PATCH v4 1/6] Introduce target_ops method thread_info_to_thread_handle Kevin Buettner
  2019-04-04 17:00 ` [PATCH v4 4/6] Tests for gdb.InferiorThread.handle Kevin Buettner
@ 2019-04-04 17:00 ` Kevin Buettner
  2019-04-04 17:00 ` [PATCH v4 2/6] Add python method InferiorThread.handle Kevin Buettner
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Kevin Buettner @ 2019-04-04 17:00 UTC (permalink / raw)
  To: gdb-patches; +Cc: Kevin Buettner

InferiorThread.handle() returns a python bytes object.  We'd like to
be able to pass the output of this function, a thread handle, to
Inferior.thread_from_thread_handle().  Up to now,
thread_from_thread_handle() expects to receive a gdb.Value input.
This commit adds support to also allow a python buffer object to be
passed as the handle.

infpy_thread_from_thread_handle() calls find_thread_by_handle() which
has the obvious functionality.  It used to pass the thread handle via
a struct value pointer.  I've revised this interface to instead pass a
gdb::array_view<const gdb_byte> object.  (Thanks to Tom Tromey for
suggesting this data structure over an earlier version which passed a
gdb_byte pointer and length.)

gdb/ChangeLog:

	* gdbthread.h (find_thread_by_handle): Revise declaration.
	* thread.c (find_thread_by_handle): Likewise.  Adjust
	implementation too.
	* python/py-inferior.c (infpy_thread_from_thread_handle): Add
	support for buffer objects as handles.
---
 gdb/gdbthread.h          |  4 ++--
 gdb/python/py-inferior.c | 25 ++++++++++++++++++++++---
 gdb/thread.c             | 10 +++++-----
 3 files changed, 29 insertions(+), 10 deletions(-)

diff --git a/gdb/gdbthread.h b/gdb/gdbthread.h
index 37c7910635..d89cadbab9 100644
--- a/gdb/gdbthread.h
+++ b/gdb/gdbthread.h
@@ -486,8 +486,8 @@ extern struct thread_info *find_thread_ptid (inferior *inf, ptid_t ptid);
 struct thread_info *find_thread_global_id (int global_id);
 
 /* Find thread by thread library specific handle in inferior INF.  */
-struct thread_info *find_thread_by_handle (struct value *thread_handle,
-					   struct inferior *inf);
+struct thread_info *find_thread_by_handle
+  (gdb::array_view<const gdb_byte> handle, struct inferior *inf);
 
 /* Finds the first thread of the specified inferior.  */
 extern struct thread_info *first_thread_of_inferior (inferior *inf);
diff --git a/gdb/python/py-inferior.c b/gdb/python/py-inferior.c
index 72fbf6d90b..7129815b21 100644
--- a/gdb/python/py-inferior.c
+++ b/gdb/python/py-inferior.c
@@ -774,7 +774,25 @@ infpy_thread_from_thread_handle (PyObject *self, PyObject *args, PyObject *kw)
   if (! gdb_PyArg_ParseTupleAndKeywords (args, kw, "O", keywords, &handle_obj))
     return NULL;
 
-  if (!gdbpy_is_value_object (handle_obj))
+  const gdb_byte *bytes;
+  size_t bytes_len;
+  Py_buffer_up buffer_up;
+  Py_buffer py_buf;
+
+  if (PyObject_CheckBuffer (handle_obj)
+      && PyObject_GetBuffer (handle_obj, &py_buf, PyBUF_SIMPLE) == 0)
+    {
+      buffer_up.reset (&py_buf);
+      bytes = (const gdb_byte *) py_buf.buf;
+      bytes_len = py_buf.len;
+    }
+  else if (gdbpy_is_value_object (handle_obj))
+    {
+      struct value *val = value_object_to_value (handle_obj);
+      bytes = value_contents_all (val);
+      bytes_len = TYPE_LENGTH (value_type (val));
+    }
+  else
     {
       PyErr_SetString (PyExc_TypeError,
 		       _("Argument 'handle_obj' must be a thread handle object."));
@@ -785,9 +803,10 @@ infpy_thread_from_thread_handle (PyObject *self, PyObject *args, PyObject *kw)
   TRY
     {
       struct thread_info *thread_info;
-      struct value *val = value_object_to_value (handle_obj);
 
-      thread_info = find_thread_by_handle (val, inf_obj->inferior);
+      thread_info = find_thread_by_handle
+        (gdb::array_view<const gdb_byte> (bytes, bytes_len),
+	 inf_obj->inferior);
       if (thread_info != NULL)
 	return thread_to_thread_object (thread_info).release ();
     }
diff --git a/gdb/thread.c b/gdb/thread.c
index 0879549b8a..8f6b762add 100644
--- a/gdb/thread.c
+++ b/gdb/thread.c
@@ -541,12 +541,12 @@ find_thread_ptid (inferior *inf, ptid_t ptid)
 /* See gdbthread.h.  */
 
 struct thread_info *
-find_thread_by_handle (struct value *thread_handle, struct inferior *inf)
+find_thread_by_handle (gdb::array_view<const gdb_byte> handle,
+		       struct inferior *inf)
 {
-  return target_thread_handle_to_thread_info
-	   (value_contents_all (thread_handle),
-	    TYPE_LENGTH (value_type (thread_handle)),
-	    inf);
+  return target_thread_handle_to_thread_info (handle.data (),
+					      handle.size (),
+					      inf);
 }
 
 /*
-- 
2.20.1

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v4 0/6] Add python method gdb.InferiorThread.handle
  2019-04-04 16:59 [PATCH v4 0/6] Add python method gdb.InferiorThread.handle Kevin Buettner
                   ` (5 preceding siblings ...)
  2019-04-04 17:00 ` [PATCH v4 5/6] Documentation for python method InferiorThread.handle Kevin Buettner
@ 2019-04-08 20:30 ` Tom Tromey
  2019-04-09  3:34   ` Kevin Buettner
  6 siblings, 1 reply; 10+ messages in thread
From: Tom Tromey @ 2019-04-08 20:30 UTC (permalink / raw)
  To: Kevin Buettner; +Cc: gdb-patches

>>>>> "Kevin" == Kevin Buettner <kevinb@redhat.com> writes:

Kevin> In v4, this version, patches 1 and 2 have been revised slightly to
Kevin> address some additional problems found by Tom Tromey.  Patches 3-6
Kevin> are unchanged, but are included for completeness.

Thanks.  I looked at the updated patches and they look good to me.

Tom

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v4 0/6] Add python method gdb.InferiorThread.handle
  2019-04-08 20:30 ` [PATCH v4 0/6] Add python method gdb.InferiorThread.handle Tom Tromey
@ 2019-04-09  3:34   ` Kevin Buettner
  0 siblings, 0 replies; 10+ messages in thread
From: Kevin Buettner @ 2019-04-09  3:34 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

On Mon, 08 Apr 2019 14:30:00 -0600
Tom Tromey <tom@tromey.com> wrote:

> >>>>> "Kevin" == Kevin Buettner <kevinb@redhat.com> writes:  
> 
> Kevin> In v4, this version, patches 1 and 2 have been revised slightly to
> Kevin> address some additional problems found by Tom Tromey.  Patches 3-6
> Kevin> are unchanged, but are included for completeness.  
> 
> Thanks.  I looked at the updated patches and they look good to me.

Thanks for all of the reviews!

I've pushed this series (after fixing a TRY/CATCH build problem and
then retesting).

Kevin

^ permalink raw reply	[flat|nested] 10+ messages in thread

* New FAILs (gdb.python/py-thrhandle.exp) on unix/-m32 (was: Re: [PATCH v4 4/6] Tests for gdb.InferiorThread.handle)
  2019-04-04 17:00 ` [PATCH v4 4/6] Tests for gdb.InferiorThread.handle Kevin Buettner
@ 2019-05-03  0:04   ` Sergio Durigan Junior
  0 siblings, 0 replies; 10+ messages in thread
From: Sergio Durigan Junior @ 2019-05-03  0:04 UTC (permalink / raw)
  To: Kevin Buettner; +Cc: gdb-patches

On Thursday, April 04 2019, Kevin Buettner wrote:

> gdb/testsuite/ChangeLog:
>
> 	* gdb.python/py-thrhandle.exp: Add tests for
> 	gdb.InferiorThread.handle.

Hey Kevin,

I've just noticed that this patch series has introduced new FAILs when
testing a 64-bit GDB with --target_board unix/-m32:

new FAIL: gdb.python/py-thrhandle.exp: thread 0: fetch thread handle from thread
new FAIL: gdb.python/py-thrhandle.exp: thread 0: verify that handles are the same
new FAIL: gdb.python/py-thrhandle.exp: thread 1: fetch thread handle from thread
new FAIL: gdb.python/py-thrhandle.exp: thread 1: verify that handles are the same
new FAIL: gdb.python/py-thrhandle.exp: thread 2: fetch thread handle from thread
new FAIL: gdb.python/py-thrhandle.exp: thread 2: verify that handles are the same

The build logs:

https://gdb-build.sergiodj.net/builders/Fedora-x86_64-m32/builds/12263

And the testsuite logs:

https://gdb-build.sergiodj.net/results/Fedora-x86_64-m32/94/947210e5690c61b395ccd887bc58bcb45ccd357b/

I haven't been able to investigate further, sorry.

Thanks,

> ---
>  gdb/testsuite/gdb.python/py-thrhandle.exp | 42 +++++++++++++++++++++--
>  1 file changed, 39 insertions(+), 3 deletions(-)
>
> diff --git a/gdb/testsuite/gdb.python/py-thrhandle.exp b/gdb/testsuite/gdb.python/py-thrhandle.exp
> index 2c905b444f..57b97faa18 100644
> --- a/gdb/testsuite/gdb.python/py-thrhandle.exp
> +++ b/gdb/testsuite/gdb.python/py-thrhandle.exp
> @@ -16,11 +16,12 @@
>  # Please email any bugs, comments, and/or additions to this file to:
>  # bug-gdb@gnu.org
>  
> -# This file verifies that gdb.Inferior.thread_from_thread_handle works
> -# as expected.
> +# This file verifies that methods Inferior.thread_from_thread_handle
> +# and InferiorThread.handle work as expected.
>  
> -standard_testfile
> +load_lib gdb-python.exp
>  
> +standard_testfile
>  
>  if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable debug] != "" } {
>      return -1
> @@ -104,3 +105,38 @@ gdb_test "python print(gdb.selected_inferior().thread_from_thread_handle(gdb.par
>  gdb_test "python print(gdb.selected_inferior().thread_from_thread_handle(gdb.parse_and_eval('\"S\"')))" \
>           ".*Thread handle size mismatch.*" \
>  	 "Pass too small of an object to thread_from_thread_handle"
> +
> +# Test the thread_handle method
> +
> +gdb_py_test_silent_cmd "python tp=gdb.lookup_type('pthread_t')" \
> +		       "Get pthread_t type" 0
> +gdb_py_test_silent_cmd "python inf=gdb.selected_inferior()" "Get inferior" 0
> +
> +foreach thrN {0 1 2} {
> +    with_test_prefix "thread $thrN" {
> +
> +	gdb_py_test_silent_cmd \
> +	    "python hand = gdb.parse_and_eval('thrs\[$thrN\]')" \
> +	    "fetch thread handle from inferior" \
> +	    1
> +
> +	gdb_py_test_silent_cmd \
> +	    "python hand_bytes = inf.thread_from_thread_handle(hand).handle()" \
> +	    "fetch thread handle from thread" \
> +	    1
> +
> +
> +	# It'd be nice to be able to use this comparison expression:
> +	#
> +	#    hand == hand_bytes
> +	#
> +	# But this won't work because hand is a gdb.Value and hand_bytes
> +	# is a Python bytes object.  Therefore, we convert the bytes
> +	# object into a gdb.value by calling the two argument form of
> +	# its constructor.
> +
> +        gdb_test "python print(gdb.Value(hand_bytes, tp) == hand)" \
> +	         "True" \
> +	         "verify that handles are the same"
> +    }
> +}
> -- 
> 2.20.1

-- 
Sergio
GPG key ID: 237A 54B1 0287 28BF 00EF  31F4 D0EB 7628 65FC 5E36
Please send encrypted e-mail if possible
http://sergiodj.net/

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2019-05-03  0:04 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-04-04 16:59 [PATCH v4 0/6] Add python method gdb.InferiorThread.handle Kevin Buettner
2019-04-04 16:59 ` [PATCH v4 1/6] Introduce target_ops method thread_info_to_thread_handle Kevin Buettner
2019-04-04 17:00 ` [PATCH v4 4/6] Tests for gdb.InferiorThread.handle Kevin Buettner
2019-05-03  0:04   ` New FAILs (gdb.python/py-thrhandle.exp) on unix/-m32 (was: Re: [PATCH v4 4/6] Tests for gdb.InferiorThread.handle) Sergio Durigan Junior
2019-04-04 17:00 ` [PATCH v4 3/6] Support buffer objects as handles in Inferior.thread_from_thread_handle() Kevin Buettner
2019-04-04 17:00 ` [PATCH v4 2/6] Add python method InferiorThread.handle Kevin Buettner
2019-04-04 17:00 ` [PATCH v4 6/6] Rename python function thread_from_thread_handle to thread_from_handle Kevin Buettner
2019-04-04 17:00 ` [PATCH v4 5/6] Documentation for python method InferiorThread.handle Kevin Buettner
2019-04-08 20:30 ` [PATCH v4 0/6] Add python method gdb.InferiorThread.handle Tom Tromey
2019-04-09  3:34   ` Kevin Buettner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).