Add Python InferiorThread.global_num attribute
authorPedro Alves <palves@redhat.com>
Wed, 13 Jan 2016 10:56:08 +0000 (10:56 +0000)
committerPedro Alves <palves@redhat.com>
Wed, 13 Jan 2016 11:00:54 +0000 (11:00 +0000)
This commit adds a new Python InferiorThread.global_num attribute.
This can be used to pass the correct thread ID to Breakpoint.thread,
which takes a global thread ID, not a per-inferior thread number.

gdb/ChangeLog:
2016-01-13  Pedro Alves  <palves@redhat.com>

* NEWS: Mention InferiorThread.global_num.
* python/py-infthread.c (thpy_get_global_num): New function.
(thread_object_getset): Register "global_num".

gdb/testsuite/ChangeLog:
2016-01-13  Pedro Alves  <palves@redhat.com>

* gdb.multi/tids.exp: Test InferiorThread.global_num and
Breakpoint.thread.
* gdb.python/py-infthread.exp: Test InferiorThread.global_num.

gdb/doc/ChangeLog:
2016-01-13  Pedro Alves  <palves@redhat.com>

* python.texi (Breakpoints In Python) <Breakpoint.thread>: Add
anchor.
(Threads In Python): Document new InferiorThread.global_num
attribute.

gdb/ChangeLog
gdb/NEWS
gdb/doc/ChangeLog
gdb/doc/python.texi
gdb/python/py-infthread.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.multi/tids.exp
gdb/testsuite/gdb.python/py-infthread.exp

index c10644bafdcc7b761577d09eccd3e4c0f93c2424..d2538084f83f7f002a1d53edde5bfafbd5f0ab43 100644 (file)
@@ -1,3 +1,9 @@
+2016-01-13  Pedro Alves  <palves@redhat.com>
+
+       * NEWS: Mention InferiorThread.global_num.
+       * python/py-infthread.c (thpy_get_global_num): New function.
+       (thread_object_getset): Register "global_num".
+
 2016-01-13  Pedro Alves  <palves@redhat.com>
 
        * NEWS: Mention that thread IDs are now per inferior and global
index 4e0ffd3a71f4c25873f20c32deff4c1c94edbbd7..ff92079301e095a60892e743d382550e4ef7fe06 100644 (file)
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -208,9 +208,10 @@ show remote catch-syscall-packet
 
 * Python Scripting
 
-  ** The "num" attribute of gdb.InferiorThread objects now refers to
-     the thread's per-inferior number.  See "Per-inferior thread
-     numbers" above.
+  ** gdb.InferiorThread objects have a new attribute "global_num",
+     which refers to the thread's global thread ID.  The existing
+     "num" attribute now refers to the thread's per-inferior number.
+     See "Per-inferior thread numbers" above.
   ** gdb.InferiorThread objects have a new attribute "inferior", which
      is the Inferior object the thread belongs to.
 
index 46207f68dfb04dc61dbbab53311a38babd8213c3..65f8ed900a70d9ae1cde397e8a59aba1b5b846da 100644 (file)
@@ -1,3 +1,10 @@
+2016-01-13  Pedro Alves  <palves@redhat.com>
+
+       * python.texi (Breakpoints In Python) <Breakpoint.thread>: Add
+       anchor.
+       (Threads In Python): Document new InferiorThread.global_num
+       attribute.
+
 2016-01-07  Pedro Alves  <palves@redhat.com>
 
        * gdb.texinfo (Threads): Document per-inferior thread IDs,
index f9f9e5b9077bc9f828a54a6ce867fd403cc7fa6b..ffbf89abcb40558a586e2a58e27f8feae0027534 100644 (file)
@@ -2998,6 +2998,12 @@ user-specified thread name.
 The per-inferior number of the thread, as assigned by GDB.
 @end defvar
 
+@defvar InferiorThread.global_num
+The global ID of the thread, as assigned by GDB.  You can use this to
+make Python breakpoints thread-specific, for example
+(@pxref{python_breakpoint_thread,,The Breakpoint.thread attribute}).
+@end defvar
+
 @defvar InferiorThread.ptid
 ID of the thread, as assigned by the operating system.  This attribute is a
 tuple containing three integers.  The first is the Process ID (PID); the second
@@ -4642,6 +4648,7 @@ first command is @code{silent}.  This is not reported by the
 @code{silent} attribute.
 @end defvar
 
+@anchor{python_breakpoint_thread}
 @defvar Breakpoint.thread
 If the breakpoint is thread-specific, this attribute holds the
 thread's global id.  If the breakpoint is not thread-specific, this
index a9dd5cb3a419a1596483b59db0895f7484ea2147..3a9bae7e8d2fb23a00f7b0ec843e3f3184367426 100644 (file)
@@ -127,6 +127,18 @@ thpy_get_num (PyObject *self, void *closure)
   return PyLong_FromLong (thread_obj->thread->per_inf_num);
 }
 
+/* Getter for InferiorThread.global_num.  */
+
+static PyObject *
+thpy_get_global_num (PyObject *self, void *closure)
+{
+  thread_object *thread_obj = (thread_object *) self;
+
+  THPY_REQUIRE_VALID (thread_obj);
+
+  return PyLong_FromLong (thread_obj->thread->global_num);
+}
+
 /* Getter for InferiorThread.ptid  -> (pid, lwp, tid).
    Returns a tuple with the thread's ptid components.  */
 
@@ -298,6 +310,8 @@ static PyGetSetDef thread_object_getset[] =
     "The name of the thread, as set by the user or the OS.", NULL },
   { "num", thpy_get_num, NULL,
     "Per-inferior number of the thread, as assigned by GDB.", NULL },
+  { "global_num", thpy_get_global_num, NULL,
+    "Global number of the thread, as assigned by GDB.", NULL },
   { "ptid", thpy_get_ptid, NULL, "ID of the thread, as assigned by the OS.",
     NULL },
   { "inferior", thpy_get_inferior, NULL,
index d9bafe133dd12c6831efb21d4a98843dbeda9a95..92989a9a9cad7e1856b4fb51a9a31663cc0ed9e6 100644 (file)
@@ -1,3 +1,9 @@
+2016-01-13  Pedro Alves  <palves@redhat.com>
+
+       * gdb.multi/tids.exp: Test InferiorThread.global_num and
+       Breakpoint.thread.
+       * gdb.python/py-infthread.exp: Test InferiorThread.global_num.
+
 2016-01-07  Pedro Alves  <palves@redhat.com>
 
        * gdb.base/break.exp: Adjust to output changes.
index 70a1d814866deb8c3104e33997f5a3a2c9373b39..6895f3c9561aa0e7819da0e4ee1dec0298a06a2d 100644 (file)
@@ -244,11 +244,28 @@ with_test_prefix "two inferiors" {
 
 if { ![skip_python_tests] } {
     with_test_prefix "python" {
-       # Check that InferiorThread.num returns the expected number.
+       # Check that InferiorThread.num and InferiorThread.global_num
+       # return the expected numbers.
        gdb_py_test_silent_cmd "python t0 = gdb.selected_thread ()" \
            "test gdb.selected_thread" 1
        gdb_test "python print ('result = %s' % t0.num)" " = 3" \
            "test InferiorThread.num"
+       gdb_test "python print ('result = %s' % t0.global_num)" " = 6" \
+           "test InferiorThread.global_num"
+
+       # Breakpoint.thread expects global IDs.  Confirm that that
+       # works as expected.
+       delete_breakpoints
+       gdb_breakpoint "thread_function1"
+
+       gdb_py_test_silent_cmd "python bp = gdb.breakpoints()\[0\]" \
+           "get python breakpoint" 0
+       gdb_test "python bp.thread = 6" "thread = 6" \
+           "make breakpoint thread-specific with python"
+       # Check that the inferior-qualified ID is correct.
+       gdb_test "info breakpoint" \
+           "stop only in thread 1.3\r\n.*" \
+           "thread specific breakpoint right thread"
     }
 }
 
index e07fd82dfab72bbf46cbe05a2ff590b469f55192..11f8d211a2d401edbd3e86bdf4fd6c917d5d6471 100644 (file)
@@ -42,6 +42,7 @@ if ![runto_main] then {
 gdb_py_test_silent_cmd "python t0 = gdb.selected_thread ()" "test gdb.selected_thread" 1
 gdb_test "python print (t0)" "\\<gdb.InferiorThread object at 0x\[\[:xdigit:\]\]+>" "verify InferiorThread object"
 gdb_test "python print ('result = %s' % t0.num)" " = 1" "test InferiorThread.num"
+gdb_test "python print ('result = %s' % t0.global_num)" " = 1" "test InferiorThread.global_num"
 gdb_test "python print ('result = %s' % str (t0.ptid))" " = \\(\[0-9\]+, \[0-9\]+, \[0-9\]+\\)" "test InferiorThread.ptid"
 
 gdb_py_test_silent_cmd "python i0 = t0.inferior" "test InferiorThread.inferior" 1