python: Add Progspace.objfiles method
authorSimon Marchi <simon.marchi@ericsson.com>
Thu, 13 Sep 2018 19:40:41 +0000 (15:40 -0400)
committerSimon Marchi <simon.marchi@ericsson.com>
Thu, 13 Sep 2018 19:42:12 +0000 (15:42 -0400)
This patch adds an objfiles method to the Progspace object, which
returns a sequence of the objfiles associated to that program space.  I
chose a method rather than a property for symmetry with gdb.objfiles().

gdb/ChangeLog:

* python/py-progspace.c (PSPY_REQUIRE_VALID): New macro.
(pspy_get_objfiles): New function.
(progspace_object_methods): New.
(pspace_object_type): Add tp_methods callback.
* python/python-internal.h (build_objfiles_list): New
declaration.
* python/python.c (build_objfiles_list): New function.
(gdbpy_objfiles): Implement using build_objfiles_list.
* NEWS: Mention the Progspace.objfiles method.

gdb/doc/ChangeLog:

* python.texi (Program Spaces In Python): Document the
Progspace.objfiles method.
(Objfiles In Python): Mention that gdb.objfiles() is identical
to gdb.selected_inferior().progspace.objfiles().

gdb/testsuite/ChangeLog:

* gdb.python/py-progspace.exp: Test the Progspace.objfiles
method.

gdb/ChangeLog
gdb/NEWS
gdb/doc/ChangeLog
gdb/doc/python.texi
gdb/python/py-progspace.c
gdb/python/python-internal.h
gdb/python/python.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.python/py-progspace.exp

index 8ec110c..4c52a65 100644 (file)
@@ -1,4 +1,17 @@
 2018-09-13  Simon Marchi  <simon.marchi@ericsson.com>
+2018-09-13  Tom Tromey  <tom@tromey.com>
+
+       * python/py-progspace.c (PSPY_REQUIRE_VALID): New macro.
+       (pspy_get_objfiles): New function.
+       (progspace_object_methods): New.
+       (pspace_object_type): Add tp_methods callback.
+       * python/python-internal.h (build_objfiles_list): New
+       declaration.
+       * python/python.c (build_objfiles_list): New function.
+       (gdbpy_objfiles): Implement using build_objfiles_list.
+       * NEWS: Mention the Progspace.objfiles method.
+
+2018-09-13  Simon Marchi  <simon.marchi@ericsson.com>
 
        * python/py-inferior.c (infpy_get_progspace): New function.
        (inferior_object_getset): Add progspace property.
index 4e26f4b..2a89569 100644 (file)
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -89,6 +89,9 @@ CSKY GNU/LINUX                        csky*-*-linux
   ** The gdb.Inferior type has a new 'progspace' property, which is the program
      space associated to that inferior.
 
+  ** The gdb.Progspace type has a new 'objfiles' method, which returns the list
+     of objfiles associated to that program space.
+
 *** Changes in GDB 8.2
 
 * The 'set disassembler-options' command now supports specifying options
index 4750c34..e6d5c8f 100644 (file)
@@ -1,6 +1,14 @@
 2018-09-13  Simon Marchi  <simon.marchi@ericsson.com>
 2018-09-13  Tom Tromey  <tom@tromey.com>
 
+       * python.texi (Program Spaces In Python): Document the
+       Progspace.objfiles method.
+       (Objfiles In Python): Mention that gdb.objfiles() is identical
+       to gdb.selected_inferior().progspace.objfiles().
+
+2018-09-13  Simon Marchi  <simon.marchi@ericsson.com>
+2018-09-13  Tom Tromey  <tom@tromey.com>
+
        * python.texi (Inferiors In Python): Document
        Inferior.progspace.
        (Program Spaces In Python): Document that
index 75d8ae1..896e27b 100644 (file)
@@ -4079,6 +4079,14 @@ Hello.
 [Inferior 1 (process 4242) exited normally]
 @end smallexample
 
+A @code{gdb.Progspace} object has the following methods:
+
+@findex Progspace.objfiles
+@defun Progspace.objfiles ()
+Return a sequence of all the objfiles referenced by this program
+space.  @xref{Objfiles In Python}.
+@end defun
+
 @node Objfiles In Python
 @subsubsection Objfiles In Python
 
@@ -4105,7 +4113,9 @@ this function returns @code{None}.
 @findex gdb.objfiles
 @defun gdb.objfiles ()
 Return a sequence of all the objfiles current known to @value{GDBN}.
-@xref{Objfiles In Python}.
+@xref{Objfiles In Python}.  This is identical to
+@code{gdb.selected_inferior().progspace.objfiles()} (@pxref{Progspaces In
+Python}) and is included for historical compatibility.
 @end defun
 
 @findex gdb.lookup_objfile
index 3eaa466..e01338f 100644 (file)
@@ -58,7 +58,16 @@ extern PyTypeObject pspace_object_type
 
 static const struct program_space_data *pspy_pspace_data_key;
 
-\f
+/* Require that PSPACE_OBJ be a valid program space ID.  */
+#define PSPY_REQUIRE_VALID(pspace_obj)                         \
+  do {                                                         \
+    if (pspace_obj->pspace == nullptr)                         \
+      {                                                                \
+       PyErr_SetString (PyExc_RuntimeError,                    \
+                        _("Program space no longer exists.")); \
+       return NULL;                                            \
+      }                                                                \
+  } while (0)
 
 /* An Objfile method which returns the objfile's file name, or None.  */
 
@@ -314,7 +323,17 @@ pspy_set_type_printers (PyObject *o, PyObject *value, void *ignore)
   return 0;
 }
 
-\f
+/* Implement the objfiles method.  */
+
+static PyObject *
+pspy_get_objfiles (PyObject *self_, PyObject *args)
+{
+  pspace_object *self = (pspace_object *) self_;
+
+  PSPY_REQUIRE_VALID (self);
+
+  return build_objfiles_list (self->pspace).release ();
+}
 
 /* Clear the PSPACE pointer in a Pspace object and remove the reference.  */
 
@@ -397,6 +416,13 @@ static gdb_PyGetSetDef pspace_getset[] =
   { NULL }
 };
 
+static PyMethodDef progspace_object_methods[] =
+{
+  { "objfiles", pspy_get_objfiles, METH_NOARGS,
+    "Return a sequence of objfiles associated to this program space." },
+  { NULL }
+};
+
 PyTypeObject pspace_object_type =
 {
   PyVarObject_HEAD_INIT (NULL, 0)
@@ -426,7 +452,7 @@ PyTypeObject pspace_object_type =
   0,                             /* tp_weaklistoffset */
   0,                             /* tp_iter */
   0,                             /* tp_iternext */
-  0,                             /* tp_methods */
+  progspace_object_methods,      /* tp_methods */
   0,                             /* tp_members */
   pspace_getset,                 /* tp_getset */
   0,                             /* tp_base */
index 3874fdc..785ad17 100644 (file)
@@ -549,6 +549,10 @@ struct symtab_and_line *sal_object_to_symtab_and_line (PyObject *obj);
 struct frame_info *frame_object_to_frame_info (PyObject *frame_obj);
 struct gdbarch *arch_object_to_gdbarch (PyObject *obj);
 
+/* Return a Python list containing an Objfile object for each objfile in
+   PSPACE.  */
+gdbpy_ref<> build_objfiles_list (program_space *pspace);
+
 void gdbpy_initialize_gdb_readline (void);
 int gdbpy_initialize_auto_load (void)
   CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
index 6f798a0..371f4a5 100644 (file)
@@ -1437,10 +1437,10 @@ gdbpy_get_current_objfile (PyObject *unused1, PyObject *unused2)
   return result;
 }
 
-/* Return a sequence holding all the Objfiles.  */
+/* See python-internal.h.  */
 
-static PyObject *
-gdbpy_objfiles (PyObject *unused1, PyObject *unused2)
+gdbpy_ref<>
+build_objfiles_list (program_space *pspace)
 {
   struct objfile *objf;
 
@@ -1448,15 +1448,23 @@ gdbpy_objfiles (PyObject *unused1, PyObject *unused2)
   if (list == NULL)
     return NULL;
 
-  ALL_OBJFILES (objf)
-  {
-    PyObject *item = objfile_to_objfile_object (objf);
+  ALL_PSPACE_OBJFILES (pspace, objf)
+    {
+      PyObject *item = objfile_to_objfile_object (objf);
 
-    if (!item || PyList_Append (list.get (), item) == -1)
-      return NULL;
-  }
+      if (item == nullptr || PyList_Append (list.get (), item) == -1)
+       return NULL;
+    }
 
-  return list.release ();
+  return list;
+}
+
+/* Return a sequence holding all the Objfiles.  */
+
+static PyObject *
+gdbpy_objfiles (PyObject *unused1, PyObject *unused2)
+{
+  return build_objfiles_list (current_program_space).release ();
 }
 
 /* Compute the list of active python type printers and store them in
index 553eaab..97613f3 100644 (file)
@@ -1,5 +1,10 @@
 2018-09-13  Simon Marchi  <simon.marchi@ericsson.com>
 
+       * gdb.python/py-progspace.exp: Test the Progspace.objfiles
+       method.
+
+2018-09-13  Simon Marchi  <simon.marchi@ericsson.com>
+
        * gdb.python/py-inferior.exp: Add tests for Inferior.progspace
        and a few other Inferior properties when the Inferior is no
        longer valid.
index f0cafa8..fa1ffd9 100644 (file)
@@ -51,3 +51,34 @@ gdb_py_test_silent_cmd "python progspace.random_attribute = 42" \
     "Set random attribute in progspace" 1
 gdb_test "python print (progspace.random_attribute)" "42" \
     "Verify set of random attribute in progspace"
+
+if {![runto_main]} {
+    fail "can't run to main"
+    return
+}
+
+# With a single inferior, progspace.objfiles () and gdb.objfiles () should
+# be identical.
+gdb_test "python print (progspace.objfiles () == gdb.objfiles ())" "True"
+
+gdb_test "add-inferior"
+gdb_test "inferior 2"
+
+gdb_load ${binfile}
+
+# With a second (non-started) inferior, we should have a single objfile - the
+# main one.
+gdb_test "python print (len (gdb.objfiles ())) == 1"
+
+# And the gdb.objfiles() list should now be different from the objfiles of the
+# prog space of inferior 1.
+gdb_test "python print (progspace.objfiles () != gdb.objfiles ())" "True"
+
+# Delete inferior 2 (and therefore the second progspace), check that the Python
+# object reacts sensibly.
+gdb_py_test_silent_cmd "python progspace2 = gdb.current_progspace()" \
+    "save progspace 2" 1
+gdb_test "inferior 1" "Switching to inferior 1.*"
+gdb_test_no_output "remove-inferiors 2"
+gdb_test "python print (progspace2.objfiles ())" \
+    "RuntimeError: Program space no longer exists.*"