public inbox for archer@sourceware.org
 help / color / mirror / Atom feed
* [python][rfc] Add more attributes and methods to Inferior and InferiorThread.
@ 2009-04-18 22:39 Thiago Jung Bauermann
  2009-04-22  1:37 ` Tom Tromey
  0 siblings, 1 reply; 2+ messages in thread
From: Thiago Jung Bauermann @ 2009-04-18 22:39 UTC (permalink / raw)
  To: archer ml

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;
+}
+
 \f
 
 /* 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;
+}
+
 \f
 
 /* 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"


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

* Re: [python][rfc] Add more attributes and methods to Inferior and InferiorThread.
  2009-04-18 22:39 [python][rfc] Add more attributes and methods to Inferior and InferiorThread Thiago Jung Bauermann
@ 2009-04-22  1:37 ` Tom Tromey
  0 siblings, 0 replies; 2+ messages in thread
From: Tom Tromey @ 2009-04-22  1:37 UTC (permalink / raw)
  To: Thiago Jung Bauermann; +Cc: archer ml

Thiago> In particular, I'm not sure if the way I implemented is_remote
Thiago> and is_corefile is a good one, or a hack (it does work,
Thiago> though).

Haha, those look like they can't really be right :-)
I don't know the real answer though.

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

I'm not sure about what bits are useful here, either.

Also, instead of a tuple, maybe a plain object with attributes, like
we do for the fields of a type?  This seems friendlier in that users
won't have to remember the ordering.

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

For the record, this is fine by me.  I think we should probably pull
some of the comments from gdbthread.h into the documentation, so that
users can understand the differences here.

Tom

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

end of thread, other threads:[~2009-04-22  1:37 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-04-18 22:39 [python][rfc] Add more attributes and methods to Inferior and InferiorThread Thiago Jung Bauermann
2009-04-22  1:37 ` Tom Tromey

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).