python: Add Progspace.objfiles method

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.
This commit is contained in:
Simon Marchi 2018-09-13 15:40:41 -04:00
parent a40bf0c2e9
commit 0ae1a3211a
9 changed files with 122 additions and 14 deletions

View file

@ -1,3 +1,16 @@
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> 2018-09-13 Simon Marchi <simon.marchi@ericsson.com>
* python/py-inferior.c (infpy_get_progspace): New function. * python/py-inferior.c (infpy_get_progspace): New function.

View file

@ -89,6 +89,9 @@ CSKY GNU/LINUX csky*-*-linux
** The gdb.Inferior type has a new 'progspace' property, which is the program ** The gdb.Inferior type has a new 'progspace' property, which is the program
space associated to that inferior. 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 *** Changes in GDB 8.2
* The 'set disassembler-options' command now supports specifying options * The 'set disassembler-options' command now supports specifying options

View file

@ -1,3 +1,11 @@
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 Simon Marchi <simon.marchi@ericsson.com>
2018-09-13 Tom Tromey <tom@tromey.com> 2018-09-13 Tom Tromey <tom@tromey.com>

View file

@ -4079,6 +4079,14 @@ Hello.
[Inferior 1 (process 4242) exited normally] [Inferior 1 (process 4242) exited normally]
@end smallexample @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 @node Objfiles In Python
@subsubsection Objfiles In Python @subsubsection Objfiles In Python
@ -4105,7 +4113,9 @@ this function returns @code{None}.
@findex gdb.objfiles @findex gdb.objfiles
@defun gdb.objfiles () @defun gdb.objfiles ()
Return a sequence of all the objfiles current known to @value{GDBN}. 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 @end defun
@findex gdb.lookup_objfile @findex gdb.lookup_objfile

View file

@ -58,7 +58,16 @@ extern PyTypeObject pspace_object_type
static const struct program_space_data *pspy_pspace_data_key; static const struct program_space_data *pspy_pspace_data_key;
/* 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. */ /* 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; return 0;
} }
/* 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. */ /* Clear the PSPACE pointer in a Pspace object and remove the reference. */
@ -397,6 +416,13 @@ static gdb_PyGetSetDef pspace_getset[] =
{ NULL } { 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 = PyTypeObject pspace_object_type =
{ {
PyVarObject_HEAD_INIT (NULL, 0) PyVarObject_HEAD_INIT (NULL, 0)
@ -426,7 +452,7 @@ PyTypeObject pspace_object_type =
0, /* tp_weaklistoffset */ 0, /* tp_weaklistoffset */
0, /* tp_iter */ 0, /* tp_iter */
0, /* tp_iternext */ 0, /* tp_iternext */
0, /* tp_methods */ progspace_object_methods, /* tp_methods */
0, /* tp_members */ 0, /* tp_members */
pspace_getset, /* tp_getset */ pspace_getset, /* tp_getset */
0, /* tp_base */ 0, /* tp_base */

View 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 frame_info *frame_object_to_frame_info (PyObject *frame_obj);
struct gdbarch *arch_object_to_gdbarch (PyObject *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); void gdbpy_initialize_gdb_readline (void);
int gdbpy_initialize_auto_load (void) int gdbpy_initialize_auto_load (void)
CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;

View file

@ -1437,10 +1437,10 @@ gdbpy_get_current_objfile (PyObject *unused1, PyObject *unused2)
return result; return result;
} }
/* Return a sequence holding all the Objfiles. */ /* See python-internal.h. */
static PyObject * gdbpy_ref<>
gdbpy_objfiles (PyObject *unused1, PyObject *unused2) build_objfiles_list (program_space *pspace)
{ {
struct objfile *objf; struct objfile *objf;
@ -1448,15 +1448,23 @@ gdbpy_objfiles (PyObject *unused1, PyObject *unused2)
if (list == NULL) if (list == NULL)
return NULL; return NULL;
ALL_OBJFILES (objf) ALL_PSPACE_OBJFILES (pspace, objf)
{ {
PyObject *item = objfile_to_objfile_object (objf); PyObject *item = objfile_to_objfile_object (objf);
if (!item || PyList_Append (list.get (), item) == -1) if (item == nullptr || PyList_Append (list.get (), item) == -1)
return NULL; 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 /* Compute the list of active python type printers and store them in

View file

@ -1,3 +1,8 @@
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> 2018-09-13 Simon Marchi <simon.marchi@ericsson.com>
* gdb.python/py-inferior.exp: Add tests for Inferior.progspace * gdb.python/py-inferior.exp: Add tests for Inferior.progspace

View file

@ -51,3 +51,34 @@ gdb_py_test_silent_cmd "python progspace.random_attribute = 42" \
"Set random attribute in progspace" 1 "Set random attribute in progspace" 1
gdb_test "python print (progspace.random_attribute)" "42" \ gdb_test "python print (progspace.random_attribute)" "42" \
"Verify set of random attribute in progspace" "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.*"