This is the mail archive of the archer@sourceware.org mailing list for the Archer project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[python][rfc] Add more attributes and methods to Inferior andInferiorThread.


Hi,

This patch adds some attributes and methods to the Inferior and
InferiorThread classes, mainly to enable getting their state.

I'd appreciate comments about them, and also on how they are
implemented.

In particular, I'm not sure if the way I implemented is_remote and
is_corefile is a good one, or a hack (it does work, though). Also, even
though internally in GDB they are a property of the target, I expose
them to Python as properties of the inferior. IMHO it makes more sense,
especially if/when multi-process GDB is also capable of having inferiors
running on different targets.

Also, for the InferiorThread class, I wasn't sure which identifier to
provide. I decided to provide the full ptid, as a tuple with the pid,
lwp and tid.

As for the thread state, Tromey's initial idea was to have one state
method which would return the state. gdbthread.h says that the state_
member of thread_info is private, though, and tells interested users to
call is_{running,stopped,exited}. So I exposed these methods instead.

WDYT?
-- 
[]'s
Thiago Jung Bauermann
IBM Linux Technology Center


gdb/
	* python/python-inferior.c (infpy_get_is_remote,
	infpy_get_is_corefile): New functions.
	(inferior_object_getset): Add `is_remote' and `is_corefile'
	items.
	* python/python-infthread.c (thpy_get_ptid, thpy_is_stopped,
	thpy_is_running, thpy_is_exited): New functions.
	(thread_object_getset): Add `ptid' item.
	(thread_object_methods): Add `is_stopped', `is_running' and
	`is_exited' methods.

gdb/doc/
	* gdb.texinfo (Inferiors In Python): Document `is_remote' and
	`is_corefile' attributes.
	(Threads In Python): Document `ptid' attribute, and
	`is_stopped', `is_running' and `is_exited' methods.

gdb/testsuite/
	* testsuite/gdb.python/python-inferior.exp: Test
	Inferior.is_remote and Inferior.is_corefile.
	* testsuite/gdb.python/python-infthread.exp: Test
	inferiorThread.is_stopped, InferiorThread.is_running and
	InferiorThread.is_exited.

diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 958a74f..b2e853c 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -18904,6 +18904,15 @@ Process ID of the inferior, assigned by the underlying OS.
 Boolean signaling whether the inferior was created using `attach', or
 started by @value{GDBN} itself.
 @end defivar
+
+@defivar Inferior is_remote
+Boolean signaling whether @value{GDBN} is accessing the inferior via the
+remote protocol.
+@end defivar
+
+@defivar Inferior is_corefile
+Boolean signaling whether the inferior is being read from a corefile.
+@end defivar
 @end table
 
 A @code{gdb.Inferior} object has the following methods:
@@ -18970,6 +18979,14 @@ A @code{gdb.InferiorThread} object has the following attributes:
 @defivar InferiorThread num 
 ID of the thread, as assigned by GDB.
 @end defivar
+
+@defivar 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
+is the Lightweight Process ID (TID), and the third is the Thread ID (TID).
+Either the TID or TID may be 0, which indicates that the operating system
+doesn't use that identifier.
+@end defivar
 @end table
 
 A @code{gdb.InferiorThread} object has the following methods:
@@ -18987,6 +19004,18 @@ Return the newest frame thread's stack.
 This changes @value{GDBN}'s currently selected thread to the one represented
 by this object.
 @end defmethod
+
+@defmethod InferiorThread is_stopped
+Return a Boolean indicating whether the thread is stopped.
+@end defmethod
+
+@defmethod InferiorThread is_running
+Return a Boolean indicating whether the thread is running.
+@end defmethod
+
+@defmethod InferiorThread is_exited
+Return a Boolean indicating whether the thread is exited.
+@end defmethod
 @end table
 
 @node Commands In Python
diff --git a/gdb/python/python-inferior.c b/gdb/python/python-inferior.c
index a08be7b..e4759f7 100644
--- a/gdb/python/python-inferior.c
+++ b/gdb/python/python-inferior.c
@@ -332,6 +332,47 @@ infpy_get_was_attached (PyObject *self, void *closure)
   INFPY_REQUIRE_VALID (inf);
   if (inf->inferior->attach_flag)
     Py_RETURN_TRUE;
+
+  Py_RETURN_FALSE;
+}
+
+/* Implementation of gdb.is_remote -> Boolean.
+   Returns True if GDB is accessing the inferior via the remote protocol.  */
+
+static PyObject *
+infpy_get_is_remote (PyObject *self, void *closure)
+{
+  inferior_object *inf = (inferior_object *) self;
+  struct target_ops *t;
+
+  INFPY_REQUIRE_VALID (inf);
+
+  for (t = &current_target; t != NULL; t = t->beneath)
+    if (!strcmp (t->to_shortname, "remote"))
+    Py_RETURN_TRUE;
+
+  Py_RETURN_FALSE;
+}
+
+/* Implementation of gdb.is_corefile -> Boolean.
+   Returns True if the Inferior is being read from a corefile.  */
+
+static PyObject *
+infpy_get_is_corefile (PyObject *self, void *closure)
+{
+  inferior_object *inf = (inferior_object *) self;
+  struct target_ops *t;
+
+  INFPY_REQUIRE_VALID (inf);
+
+  for (t = &current_target; t != NULL; t = t->beneath)
+    {
+      if (!strcmp (t->to_shortname, "core"))
+	Py_RETURN_TRUE;
+      else if (!strcmp (t->to_shortname, "solaris-core"))
+	Py_RETURN_TRUE;
+    }
+
   Py_RETURN_FALSE;
 }
 
@@ -796,6 +837,10 @@ static PyGetSetDef inferior_object_getset[] =
     NULL },
   { "was_attached", infpy_get_was_attached, NULL,
     "True if the inferior was created using 'attach'.", NULL },
+  { "is_remote", infpy_get_is_remote, NULL,
+    "True if GDB is accessing the inferior via the remote protocol.", NULL },
+  { "is_corefile", infpy_get_is_corefile, NULL,
+    "True if the Inferior is being read from a corefile.", NULL },
 
   { NULL }
 };
diff --git a/gdb/python/python-infthread.c b/gdb/python/python-infthread.c
index 21e4eab..2be10d1 100644
--- a/gdb/python/python-infthread.c
+++ b/gdb/python/python-infthread.c
@@ -73,6 +73,34 @@ thpy_get_num (PyObject *self, void *closure)
   return PyLong_FromLong (thread_obj->thread->num);
 }
 
+/* Getter for InferiorThread.ptid  -> (pid, lwp, tid).
+   Returns a tuple with the thread's ptid components.  */
+
+static PyObject *
+thpy_get_ptid (PyObject *self, void *closure)
+{
+  int pid;
+  long tid, lwp;
+  thread_object *thread_obj = (thread_object *) self;
+  PyObject *ret;
+
+  THPY_REQUIRE_VALID (thread_obj);
+
+  ret = PyTuple_New (3);
+  if (!ret)
+    return NULL;
+
+  pid = ptid_get_pid (thread_obj->thread->ptid);
+  lwp = ptid_get_lwp (thread_obj->thread->ptid);
+  tid = ptid_get_tid (thread_obj->thread->ptid);
+
+  PyTuple_SET_ITEM (ret, 0, PyInt_FromLong (pid));
+  PyTuple_SET_ITEM (ret, 1, PyInt_FromLong (lwp));
+  PyTuple_SET_ITEM (ret, 2, PyInt_FromLong (tid));
+
+  return ret;
+}
+
 
 
 /* Implementation of Inferior.frames () -> (gdb.Frame, ...).
@@ -186,6 +214,54 @@ thpy_switch (PyObject *self, PyObject *args)
   Py_RETURN_NONE;
 }
 
+/* Implementation of InferiorThread.is_stopped () -> Boolean.
+   Return whether the thread is stopped.  */
+
+static PyObject *
+thpy_is_stopped (PyObject *self, PyObject *args)
+{
+  thread_object *thread_obj = (thread_object *) self;
+
+  THPY_REQUIRE_VALID (thread_obj);
+
+  if (is_stopped (thread_obj->thread->ptid))
+    Py_RETURN_TRUE;
+
+  Py_RETURN_FALSE;
+}
+
+/* Implementation of InferiorThread.is_running () -> Boolean.
+   Return whether the thread is running.  */
+
+static PyObject *
+thpy_is_running (PyObject *self, PyObject *args)
+{
+  thread_object *thread_obj = (thread_object *) self;
+
+  THPY_REQUIRE_VALID (thread_obj);
+
+  if (is_running (thread_obj->thread->ptid))
+    Py_RETURN_TRUE;
+
+  Py_RETURN_FALSE;
+}
+
+/* Implementation of InferiorThread.is_exited () -> Boolean.
+   Return whether the thread is exited.  */
+
+static PyObject *
+thpy_is_exited (PyObject *self, PyObject *args)
+{
+  thread_object *thread_obj = (thread_object *) self;
+
+  THPY_REQUIRE_VALID (thread_obj);
+
+  if (is_exited (thread_obj->thread->ptid))
+    Py_RETURN_TRUE;
+
+  Py_RETURN_FALSE;
+}
+
 
 
 /* Implementation of gdb.selected_thread () -> gdb.InferiorThread.
@@ -223,6 +299,8 @@ gdbpy_initialize_thread (void)
 static PyGetSetDef thread_object_getset[] =
 {
   { "num", thpy_get_num, NULL, "ID of the thread, as assigned by GDB.", NULL },
+  { "ptid", thpy_get_ptid, NULL, "ID of the thread, as assigned by the OS.",
+    NULL },
 
   { NULL }
 };
@@ -238,6 +316,15 @@ Return the newest frame in the thread." },
   { "switch", thpy_switch, METH_NOARGS,
     "switch ()\n\
 Makes this the GDB selected thread." },
+  { "is_stopped", thpy_is_stopped, METH_NOARGS,
+    "is_stopped () -> Boolean\n\
+Return whether the thread is stopped." },
+  { "is_running", thpy_is_running, METH_NOARGS,
+    "is_running () -> Boolean\n\
+Return whether the thread is running." },
+  { "is_exited", thpy_is_exited, METH_NOARGS,
+    "is_exited () -> Boolean\n\
+Return whether the thread is exited." },
 
   { NULL }
 };
diff --git a/gdb/testsuite/gdb.python/python-inferior.exp b/gdb/testsuite/gdb.python/python-inferior.exp
index f475ec8..715ec89 100644
--- a/gdb/testsuite/gdb.python/python-inferior.exp
+++ b/gdb/testsuite/gdb.python/python-inferior.exp
@@ -59,6 +59,15 @@ gdb_test "python print 'result =', i0 == inferiors\[0\]" " = True" "test equalit
 gdb_test "python print 'result =', i0.num" " = \[0-9\]+" "test Inferior.num"
 gdb_test "python print 'result =', i0.pid" " = \[0-9\]+" "test Inferior.pid"
 gdb_test "python print 'result =', i0.was_attached" " = False" "test Inferior.was_attached"
+
+if [is_remote target] {
+  gdb_test "python print 'result =', i0.is_remote" " = True" "test Inferior.is_remote"
+} else {
+  gdb_test "python print 'result =', i0.is_remote" " = False" "test Inferior.is_remote"
+}
+
+gdb_test "python print 'result =', i0.is_corefile" " = False" "test Inferior.is_corefile"
+
 gdb_test "python print i0.threads ()" "\\(<gdb.InferiorThread object at 0x\[\[:xdigit:\]\]+>,\\)" "test Inferior.threads"
 
 # Test memory read and write operations.
diff --git a/gdb/testsuite/gdb.python/python-infthread.exp b/gdb/testsuite/gdb.python/python-infthread.exp
index 0660f84..b5c764b 100644
--- a/gdb/testsuite/gdb.python/python-infthread.exp
+++ b/gdb/testsuite/gdb.python/python-infthread.exp
@@ -54,3 +54,8 @@ runto [gdb_get_line_number "Break here."]
 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 =', t0.num" " = \[0-9\]+" "test Inferior.num"
+gdb_test "python print 'result =', t0.ptid" " = \\(\[0-9\]+, \[0-9\]+, \[0-9\]+\\)" "test InferiorThread.ptid"
+
+gdb_test "python print 'result =', t0.is_stopped ()" " = True" "test InferiorThread.is_stopped"
+gdb_test "python print 'result =', t0.is_running ()" " = False" "test InferiorThread.is_running"
+gdb_test "python print 'result =', t0.is_exited ()" " = False" "test InferiorThread.is_exited"



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]