Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [RFA][python] Add program space support
@ 2010-04-07 17:32 Doug Evans
  2010-04-07 17:39 ` Doug Evans
  2010-04-07 17:52 ` Eli Zaretskii
  0 siblings, 2 replies; 9+ messages in thread
From: Doug Evans @ 2010-04-07 17:32 UTC (permalink / raw)
  To: gdb-patches

Hi.

This patch adds basic support for program spaces to python.

It also adds support for recording pretty-printers with a program space.
This is useful, for example, when a class is entirely inlined and there
isn't necessarily a .so to attach the pretty-printer to.
Adding the pretty-printer to the gdb module isn't necessarily correct,
different programs may have different implementations for the same class.

Ok to check in?

2010-04-07  Doug Evans  <dje@google.com>

	* Makefile.in (SUBDIR_PYTHON_OBS): Add py-progspace.o.
	(SUBDIR_PYTHON_SRCS): Add py-progspace.c.
	(py-progspace.o): New rule.
	* python/py-prettyprint.c (find_pretty_printer_from_objfiles): New
	function.
	(find_pretty_printer_from_progspace): New function.
	(find_pretty_printer_from_gdb): New function.
	(find_pretty_printer): Rewrite.
	* python/py-progspace.c: New file.
	* python/python-internal.h (program_space): Add forward decl.
	(pspace_to_pspace_object, pspy_get_printers): Declare.
	(gdbpy_initialize_pspace): Declare.
	* python/python.c: #include "progspace.h".
	(gdbpy_get_current_progspace, gdbpy_progspaces): New functions.
	(_initialize_python): Call gdbpy_initialize_pspace.
	(GdbMethods): Add current_progspace, progspaces.

	doc/
	* gdb.texinfo (Python API): Add progspaces section.
	(Selecting Pretty-Printers): Progspace pretty-printers are
	searched too.

	testsuite/
	* gdb.python/py-progspace.c: New file.
	* gdb.python/py-progspace.exp: New file.

Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.1116
diff -u -p -r1.1116 Makefile.in
--- Makefile.in	23 Mar 2010 21:31:29 -0000	1.1116
+++ Makefile.in	7 Apr 2010 17:09:56 -0000
@@ -274,6 +274,7 @@ SUBDIR_PYTHON_OBS = \
 	py-lazy-string.o \
 	py-objfile.o \
 	py-prettyprint.o \
+	py-progspace.o \
 	py-symbol.o \
 	py-symtab.o \
 	py-type.o \
@@ -288,6 +289,7 @@ SUBDIR_PYTHON_SRCS = \
 	python/py-lazy-string.c \
 	python/py-objfile.c \
 	python/py-prettyprint.c \
+	python/py-progspace.c \
 	python/py-symbol.c \
 	python/py-symtab.c \
 	python/py-type.c \
@@ -2010,6 +2012,10 @@ py-prettyprint.o: $(srcdir)/python/py-pr
 	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-prettyprint.c
 	$(POSTCOMPILE)
 
+py-progspace.o: $(srcdir)/python/py-progspace.c
+	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-progspace.c
+	$(POSTCOMPILE)
+
 py-symbol.o: $(srcdir)/python/py-symbol.c
 	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-symbol.c
 	$(POSTCOMPILE)
Index: doc/gdb.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
retrieving revision 1.696
diff -u -p -r1.696 gdb.texinfo
--- doc/gdb.texinfo	5 Apr 2010 17:14:57 -0000	1.696
+++ doc/gdb.texinfo	7 Apr 2010 17:09:56 -0000
@@ -19704,6 +19704,7 @@ situation, a Python @code{KeyboardInterr
 * Selecting Pretty-Printers::   How GDB chooses a pretty-printer.
 * Commands In Python::          Implementing new commands in Python.
 * Functions In Python::         Writing new convenience functions.
+* Progspaces In Python::        Program spaces.
 * Objfiles In Python::          Object files.
 * Frames In Python::            Accessing inferior stack frames from Python.
 * Blocks In Python::            Accessing frame blocks from Python.
@@ -20432,6 +20433,7 @@ If the result is not one of these types,
 
 The Python list @code{gdb.pretty_printers} contains an array of
 functions that have been registered via addition as a pretty-printer.
+Each @code{gdb.Progspace} contains a @code{pretty_printers} attribute.
 Each @code{gdb.Objfile} also contains a @code{pretty_printers}
 attribute.
 
@@ -20442,8 +20444,12 @@ cannot create a pretty-printer for the v
 @code{None}.
 
 @value{GDBN} first checks the @code{pretty_printers} attribute of each
-@code{gdb.Objfile} and iteratively calls each function in the list for
-that @code{gdb.Objfile} until it receives a pretty-printer object.
+@code{gdb.Objfile} in the current program space and iteratively calls
+each function in the list for that @code{gdb.Objfile} until it receives
+a pretty-printer object.
+If no pretty-printer is found in the objfile lists, @value{GDBN} then
+searches the pretty-printer list of the current program space,
+calling each function until an object is returned.
 After these lists have been exhausted, it tries the global
 @code{gdb.pretty-printers} list, again calling each function until an
 object is returned.
@@ -20841,6 +20847,47 @@ registration of the function with @value
 Python code is read into @value{GDBN}, you may need to import the
 @code{gdb} module explicitly.
 
+@node Progspaces In Python
+@subsubsection Progspaces In Python
+
+@cindex progspaces in python
+@tindex gdb.Progspace
+@tindex Progspace
+A program space, or ``progspace'', represents a symbolic view
+of an address space.
+It consists of all of the objfiles of the program.
+@xref{Objfiles In Python}.
+
+The following progspace-related functions are available in the
+@code{gdb} module:
+
+@findex gdb.current_progspace
+@defun current_progspace
+This function returns the program space of the currently selected inferior.
+@xref{Inferiors and Programs}.
+@end defun
+
+@findex gdb.progspaces
+@defun progspaces
+Return a sequence of all the progspaces currently known to @value{GDBN}.
+@end defun
+
+Each progspace is represented by an instance of the @code{gdb.Progspace}
+class.
+
+@defivar Progspace filename
+The file name of the progspace as a string.
+@end defivar
+
+@defivar Progspace pretty_printers
+The @code{pretty_printers} attribute is a list of functions.  It is
+used to look up pretty-printers.  A @code{Value} is passed to each
+function in order; if the function returns @code{None}, then the
+search continues.  Otherwise, the return value should be an object
+which is used to format the value.  @xref{Pretty Printing}, for more
+information.
+@end defivar
+
 @node Objfiles In Python
 @subsubsection Objfiles In Python
 
Index: python/py-prettyprint.c
===================================================================
RCS file: /cvs/src/src/gdb/python/py-prettyprint.c,v
retrieving revision 1.5
diff -u -p -r1.5 py-prettyprint.c
--- python/py-prettyprint.c	2 Feb 2010 16:45:16 -0000	1.5
+++ python/py-prettyprint.c	7 Apr 2010 17:09:56 -0000
@@ -29,12 +29,12 @@
 #ifdef HAVE_PYTHON
 #include "python-internal.h"
 
-
 /* Helper function for find_pretty_printer which iterates over a list,
    calls each function and inspects output.  This will return a
    printer object if one recognizes VALUE.  If no printer is found, it
    will return None.  On error, it will set the Python error and
    return NULL.  */
+
 static PyObject *
 search_pp_list (PyObject *list, PyObject *value)
 {
@@ -60,18 +60,19 @@ search_pp_list (PyObject *list, PyObject
   Py_RETURN_NONE;
 }
 
-/* Find the pretty-printing constructor function for VALUE.  If no
-   pretty-printer exists, return None.  If one exists, return a new
-   reference.  On error, set the Python error and return NULL.  */
+/* Subroutine of find_pretty_printer to simplify it.
+   Look for a pretty-printer to print VALUE in all objfiles.
+   The result is NULL if there's an error and the search should be terminated.
+   The result is Py_None, suitably inc-ref'd, if no pretty-printer was found.
+   Otherwise the result is the pretty-printer function, suitably inc-ref'd.  */
+
 static PyObject *
-find_pretty_printer (PyObject *value)
+find_pretty_printer_from_objfiles (PyObject *value)
 {
-  PyObject *pp_list = NULL;
-  PyObject *function = NULL;
+  PyObject *pp_list;
+  PyObject *function;
   struct objfile *obj;
-  volatile struct gdb_exception except;
 
-  /* Look at the pretty-printer dictionary for each objfile.  */
   ALL_OBJFILES (obj)
   {
     PyObject *objf = objfile_to_objfile_object (obj);
@@ -84,44 +85,95 @@ find_pretty_printer (PyObject *value)
 
     pp_list = objfpy_get_printers (objf, NULL);
     function = search_pp_list (pp_list, value);
+    Py_XDECREF (pp_list);
 
-    /* If there is an error in any objfile list, abort the search and
-       exit.  */
+    /* If there is an error in any objfile list, abort the search and exit.  */
     if (! function)
-      {
-	Py_XDECREF (pp_list);
-	return NULL;
-      }
+      return NULL;
 
     if (function != Py_None)
-      goto done;
+      return function;
     
     Py_DECREF (function);
-    Py_XDECREF (pp_list);
   }
 
-  pp_list = NULL;
+  Py_RETURN_NONE;
+}
+
+/* Subroutine of find_pretty_printer to simplify it.
+   Look for a pretty-printer to print VALUE in the current program space.
+   The result is NULL if there's an error and the search should be terminated.
+   The result is Py_None, suitably inc-ref'd, if no pretty-printer was found.
+   Otherwise the result is the pretty-printer function, suitably inc-ref'd.  */
+
+static PyObject *
+find_pretty_printer_from_progspace (PyObject *value)
+{
+  PyObject *pp_list;
+  PyObject *function;
+  PyObject *obj = pspace_to_pspace_object (current_program_space);
+
+  if (!obj)
+    return NULL;
+  pp_list = pspy_get_printers (obj, NULL);
+  function = search_pp_list (pp_list, value);
+  Py_XDECREF (pp_list);
+  return function;
+}
+
+/* Subroutine of find_pretty_printer to simplify it.
+   Look for a pretty-printer to print VALUE in the gdb module.
+   The result is NULL if there's an error and the search should be terminated.
+   The result is Py_None, suitably inc-ref'd, if no pretty-printer was found.
+   Otherwise the result is the pretty-printer function, suitably inc-ref'd.  */
+
+static PyObject *
+find_pretty_printer_from_gdb (PyObject *value)
+{
+  PyObject *pp_list;
+  PyObject *function;
+
   /* Fetch the global pretty printer dictionary.  */
   if (! PyObject_HasAttrString (gdb_module, "pretty_printers"))
+    Py_RETURN_NONE;
+  pp_list = PyObject_GetAttrString (gdb_module, "pretty_printers");
+  if (pp_list == NULL || ! PyList_Check (pp_list))
     {
-      function = Py_None;
-      Py_INCREF (function);
-      goto done;
+      Py_XDECREF (pp_list);
+      Py_RETURN_NONE;
     }
-  pp_list = PyObject_GetAttrString (gdb_module, "pretty_printers");
-  if (! pp_list)
-    goto done;
-  if (! PyList_Check (pp_list))
-    goto done;
 
   function = search_pp_list (pp_list, value);
-
- done:
   Py_XDECREF (pp_list);
-  
   return function;
 }
 
+/* Find the pretty-printing constructor function for VALUE.  If no
+   pretty-printer exists, return None.  If one exists, return a new
+   reference.  On error, set the Python error and return NULL.  */
+
+static PyObject *
+find_pretty_printer (PyObject *value)
+{
+  PyObject *function;
+
+  /* Look at the pretty-printer dictionary for each objfile
+     in the current program-space.  */
+  function = find_pretty_printer_from_objfiles (value);
+  if (function == NULL || function != Py_None)
+    return function;
+  Py_DECREF (function);
+
+  /* Look at the pretty-printer dictionary for the current program-space.  */
+  function = find_pretty_printer_from_progspace (value);
+  if (function == NULL || function != Py_None)
+    return function;
+  Py_DECREF (function);
+
+  /* Look at the pretty-printer dictionary in the gdb module.  */
+  function = find_pretty_printer_from_gdb (value);
+  return function;
+}
 
 /* Pretty-print a single value, via the printer object PRINTER.
    If the function returns a string, a PyObject containing the string
Index: python/py-progspace.c
===================================================================
RCS file: python/py-progspace.c
diff -N python/py-progspace.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ python/py-progspace.c	7 Apr 2010 17:09:56 -0000
@@ -0,0 +1,240 @@
+/* Python interface to program spaces.
+
+   Copyright (C) 2010 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include "defs.h"
+#include "python-internal.h"
+#include "charset.h"
+#include "progspace.h"
+#include "objfiles.h"
+#include "language.h"
+
+typedef struct
+{
+  PyObject_HEAD
+
+  /* The corresponding pspace.  */
+  struct program_space *pspace;
+
+  /* The pretty-printer list of functions.  */
+  PyObject *printers;
+} pspace_object;
+
+static PyTypeObject pspace_object_type;
+
+static const struct program_space_data *pspy_pspace_data_key;
+
+\f
+
+/* An Objfile method which returns the objfile's file name, or None.  */
+
+static PyObject *
+pspy_get_filename (PyObject *self, void *closure)
+{
+  pspace_object *obj = (pspace_object *) self;
+  if (obj->pspace)
+    {
+      struct objfile *objfile = obj->pspace->symfile_object_file;
+      if (objfile && objfile->name)
+	return PyString_Decode (objfile->name, strlen (objfile->name),
+				host_charset (), NULL);
+    }
+  Py_RETURN_NONE;
+}
+
+static void
+pspy_dealloc (PyObject *self)
+{
+  pspace_object *ps_self = (pspace_object *) self;
+  Py_XDECREF (ps_self->printers);
+  self->ob_type->tp_free (self);
+}
+
+static PyObject *
+pspy_new (PyTypeObject *type, PyObject *args, PyObject *keywords)
+{
+  pspace_object *self = (pspace_object *) type->tp_alloc (type, 0);
+  if (self)
+    {
+      self->pspace = NULL;
+
+      self->printers = PyList_New (0);
+      if (!self->printers)
+	{
+	  Py_DECREF (self);
+	  return NULL;
+	}
+    }
+  return (PyObject *) self;
+}
+
+PyObject *
+pspy_get_printers (PyObject *o, void *ignore)
+{
+  pspace_object *self = (pspace_object *) o;
+  Py_INCREF (self->printers);
+  return self->printers;
+}
+
+static int
+pspy_set_printers (PyObject *o, PyObject *value, void *ignore)
+{
+  PyObject *tmp;
+  pspace_object *self = (pspace_object *) o;
+  if (! value)
+    {
+      PyErr_SetString (PyExc_TypeError,
+		       "cannot delete the pretty_printers attribute");
+      return -1;
+    }
+
+  if (! PyList_Check (value))
+    {
+      PyErr_SetString (PyExc_TypeError,
+		       "the pretty_printers attribute must be a list");
+      return -1;
+    }
+
+  /* Take care in case the LHS and RHS are related somehow.  */
+  tmp = self->printers;
+  Py_INCREF (value);
+  self->printers = value;
+  Py_XDECREF (tmp);
+
+  return 0;
+}
+
+\f
+
+/* Clear the PSPACE pointer in a Pspace object and remove the reference.  */
+
+static void
+py_free_pspace (struct program_space *pspace, void *datum)
+{
+  struct cleanup *cleanup;
+  pspace_object *object = datum;
+  /* FIXME: What's the right way to get a program space's arch?
+     There may be multiple.  */
+  struct gdbarch *arch = get_objfile_arch (pspace->symfile_object_file);
+
+  cleanup = ensure_python_env (arch, current_language);
+  object->pspace = NULL;
+  Py_DECREF ((PyObject *) object);
+  do_cleanups (cleanup);
+}
+
+/* Return a borrowed reference to the Python object of type Pspace
+   representing PSPACE.  If the object has already been created,
+   return it.  Otherwise, create it.  Return NULL and set the Python
+   error on failure.  */
+
+PyObject *
+pspace_to_pspace_object (struct program_space *pspace)
+{
+  pspace_object *object;
+
+  object = program_space_data (pspace, pspy_pspace_data_key);
+  if (!object)
+    {
+      object = PyObject_New (pspace_object, &pspace_object_type);
+      if (object)
+	{
+	  PyObject *dict;
+
+	  object->pspace = pspace;
+
+	  object->printers = PyList_New (0);
+	  if (!object->printers)
+	    {
+	      Py_DECREF (object);
+	      return NULL;
+	    }
+
+	  set_program_space_data (pspace, pspy_pspace_data_key, object);
+	}
+    }
+
+  return (PyObject *) object;
+}
+
+void
+gdbpy_initialize_pspace (void)
+{
+  pspy_pspace_data_key
+    = register_program_space_data_with_cleanup (py_free_pspace);
+
+  if (PyType_Ready (&pspace_object_type) < 0)
+    return;
+
+  Py_INCREF (&pspace_object_type);
+  PyModule_AddObject (gdb_module, "Progspace", (PyObject *) &pspace_object_type);
+}
+
+\f
+
+static PyGetSetDef pspace_getset[] =
+{
+  { "filename", pspy_get_filename, NULL,
+    "The progspace's main filename, or None.", NULL },
+  { "pretty_printers", pspy_get_printers, pspy_set_printers,
+    "Pretty printers.", NULL },
+  { NULL }
+};
+
+static PyTypeObject pspace_object_type =
+{
+  PyObject_HEAD_INIT (NULL)
+  0,				  /*ob_size*/
+  "gdb.Progspace",		  /*tp_name*/
+  sizeof (pspace_object),	  /*tp_basicsize*/
+  0,				  /*tp_itemsize*/
+  pspy_dealloc,			  /*tp_dealloc*/
+  0,				  /*tp_print*/
+  0,				  /*tp_getattr*/
+  0,				  /*tp_setattr*/
+  0,				  /*tp_compare*/
+  0,				  /*tp_repr*/
+  0,				  /*tp_as_number*/
+  0,				  /*tp_as_sequence*/
+  0,				  /*tp_as_mapping*/
+  0,				  /*tp_hash */
+  0,				  /*tp_call*/
+  0,				  /*tp_str*/
+  0,				  /*tp_getattro*/
+  0,				  /*tp_setattro*/
+  0,				  /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT,		  /*tp_flags*/
+  "GDB progspace object",	  /* tp_doc */
+  0,				  /* tp_traverse */
+  0,				  /* tp_clear */
+  0,				  /* tp_richcompare */
+  0,				  /* tp_weaklistoffset */
+  0,				  /* tp_iter */
+  0,				  /* tp_iternext */
+  0,				  /* tp_methods */
+  0,				  /* tp_members */
+  pspace_getset,		  /* tp_getset */
+  0,				  /* tp_base */
+  0,				  /* tp_dict */
+  0,				  /* tp_descr_get */
+  0,				  /* tp_descr_set */
+  0,				  /* tp_dictoffset */
+  0,				  /* tp_init */
+  0,				  /* tp_alloc */
+  pspy_new,			  /* tp_new */
+};
Index: python/python-internal.h
===================================================================
RCS file: /cvs/src/src/gdb/python/python-internal.h,v
retrieving revision 1.22
diff -u -p -r1.22 python-internal.h
--- python/python-internal.h	9 Mar 2010 17:12:40 -0000	1.22
+++ python/python-internal.h	7 Apr 2010 17:09:56 -0000
@@ -68,6 +68,7 @@ typedef int Py_ssize_t;
 struct block;
 struct value;
 struct language_defn;
+struct program_space;
 
 extern PyObject *gdb_module;
 extern PyTypeObject value_object_type;
@@ -89,8 +90,11 @@ PyObject *symbol_to_symbol_object (struc
 PyObject *block_to_block_object (struct block *block, struct objfile *objfile);
 PyObject *value_to_value_object (struct value *v);
 PyObject *type_to_type_object (struct type *);
-PyObject *objfile_to_objfile_object (struct objfile *);
 
+PyObject *pspace_to_pspace_object (struct program_space *);
+PyObject *pspy_get_printers (PyObject *, void *);
+
+PyObject *objfile_to_objfile_object (struct objfile *);
 PyObject *objfpy_get_printers (PyObject *, void *);
 
 struct block *block_object_to_block (PyObject *obj);
@@ -110,6 +114,7 @@ void gdbpy_initialize_symtabs (void);
 void gdbpy_initialize_blocks (void);
 void gdbpy_initialize_types (void);
 void gdbpy_initialize_functions (void);
+void gdbpy_initialize_pspace (void);
 void gdbpy_initialize_objfile (void);
 void gdbpy_initialize_lazy_string (void);
 
Index: python/python.c
===================================================================
RCS file: /cvs/src/src/gdb/python/python.c,v
retrieving revision 1.27
diff -u -p -r1.27 python.c
--- python/python.c	5 Mar 2010 20:18:17 -0000	1.27
+++ python/python.c	7 Apr 2010 17:09:56 -0000
@@ -23,6 +23,7 @@
 #include "ui-out.h"
 #include "cli/cli-script.h"
 #include "gdbcmd.h"
+#include "progspace.h"
 #include "objfiles.h"
 #include "observer.h"
 #include "value.h"
@@ -415,6 +416,47 @@ gdbpy_print_stack (void)
 
 \f
 
+/* Return the current Progspace.
+   There always is one.  */
+
+static PyObject *
+gdbpy_get_current_progspace (PyObject *unused1, PyObject *unused2)
+{
+  PyObject *result;
+
+  result = pspace_to_pspace_object (current_program_space);
+  if (result)
+    Py_INCREF (result);
+  return result;
+}
+
+/* Return a sequence holding all the Progspaces.  */
+
+static PyObject *
+gdbpy_progspaces (PyObject *unused1, PyObject *unused2)
+{
+  struct program_space *ps;
+  PyObject *list;
+
+  list = PyList_New (0);
+  if (!list)
+    return NULL;
+
+  ALL_PSPACES (ps)
+  {
+    PyObject *item = pspace_to_pspace_object (ps);
+    if (!item || PyList_Append (list, item) == -1)
+      {
+	Py_DECREF (list);
+	return NULL;
+      }
+  }
+
+  return list;
+}
+
+\f
+
 /* The "current" objfile.  This is set when gdb detects that a new
    objfile has been loaded.  It is only set for the duration of a call
    to gdbpy_new_objfile; it is NULL at other times.  */
@@ -510,6 +552,7 @@ gdbpy_get_current_objfile (PyObject *unu
 }
 
 /* Return a sequence holding all the Objfiles.  */
+
 static PyObject *
 gdbpy_objfiles (PyObject *unused1, PyObject *unused2)
 {
@@ -667,6 +716,7 @@ Enables or disables auto-loading of Pyth
   gdbpy_initialize_blocks ();
   gdbpy_initialize_functions ();
   gdbpy_initialize_types ();
+  gdbpy_initialize_pspace ();
   gdbpy_initialize_objfile ();
   gdbpy_initialize_lazy_string ();
 
@@ -729,6 +779,11 @@ static PyMethodDef GdbMethods[] =
   { "default_visualizer", gdbpy_default_visualizer, METH_VARARGS,
     "Find the default visualizer for a Value." },
 
+  { "current_progspace", gdbpy_get_current_progspace, METH_NOARGS,
+    "Return the current Progspace." },
+  { "progspaces", gdbpy_progspaces, METH_NOARGS,
+    "Return a sequence of all progspaces." },
+
   { "current_objfile", gdbpy_get_current_objfile, METH_NOARGS,
     "Return the current Objfile being loaded, or None." },
   { "objfiles", gdbpy_objfiles, METH_NOARGS,
Index: testsuite/gdb.python/py-progspace.c
===================================================================
RCS file: testsuite/gdb.python/py-progspace.c
diff -N testsuite/gdb.python/py-progspace.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.python/py-progspace.c	7 Apr 2010 17:09:56 -0000
@@ -0,0 +1,22 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2010 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+int
+main ()
+{
+  return 0;
+}
Index: testsuite/gdb.python/py-progspace.exp
===================================================================
RCS file: testsuite/gdb.python/py-progspace.exp
diff -N testsuite/gdb.python/py-progspace.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.python/py-progspace.exp	7 Apr 2010 17:09:56 -0000
@@ -0,0 +1,47 @@
+# Copyright (C) 2010 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# This file is part of the GDB testsuite.  It tests the program space
+# support in Python.
+
+if $tracelevel then {
+    strace $tracelevel
+}
+
+set testfile "py-progspace"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+    untested "Couldn't compile ${srcfile}"
+    return -1
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+# Skip all tests if Python scripting is not enabled.
+if { [skip_python_tests] } { continue }
+
+gdb_test "python print gdb.current_progspace().filename" "None" \
+  "current progspace filename (None)"
+gdb_test "python print gdb.progspaces()" "\\\[<gdb.Progspace object at $hex>\\\]"
+
+gdb_load ${binfile}
+
+gdb_test "python print gdb.current_progspace().filename" "py-progspace" \
+  "current progspace filename (py-progspace)"


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

* Re: [RFA][python] Add program space support
  2010-04-07 17:32 [RFA][python] Add program space support Doug Evans
@ 2010-04-07 17:39 ` Doug Evans
  2010-04-07 17:54   ` Eli Zaretskii
  2010-04-07 17:52 ` Eli Zaretskii
  1 sibling, 1 reply; 9+ messages in thread
From: Doug Evans @ 2010-04-07 17:39 UTC (permalink / raw)
  To: gdb-patches

On Wed, Apr 7, 2010 at 10:32 AM, Doug Evans <dje@google.com> wrote:
> Hi.
>
> This patch adds basic support for program spaces to python.
>
> It also adds support for recording pretty-printers with a program space.
> This is useful, for example, when a class is entirely inlined and there
> isn't necessarily a .so to attach the pretty-printer to.
> Adding the pretty-printer to the gdb module isn't necessarily correct,
> different programs may have different implementations for the same class.
>
> Ok to check in?

Blech, forgot a NEWS entry.

2010-04-07  Doug Evans  <dje@google.com>

        * NEWS: Add entry for python program space support.

Index: NEWS
===================================================================
RCS file: /cvs/src/src/gdb/NEWS,v
retrieving revision 1.367
diff -u -p -r1.367 NEWS
--- NEWS        1 Apr 2010 14:11:22 -0000       1.367
+++ NEWS        7 Apr 2010 17:38:49 -0000
@@ -25,10 +25,13 @@

 * Python scripting

-** The GDB Python API now has access to symbols, symbol tables, and
-   frame's code blocks.
+** The GDB Python API now has access to program spaces, symbols,
+   symbol tables, and frame's code blocks.

-** New methods gdb.target_charset and gdb.target_wide_charset.
+** New methods gdb.target_charset, gdb.target_wide_charset,
+   gdb.progspaces, and gdb.current_progspace.
+
+** Pretty-printers are now also looked up in the current program space.

 * Tracepoint actions were unified with breakpoint commands. In particular,
 there are no longer differences in "info break" output for breakpoints and


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

* Re: [RFA][python] Add program space support
  2010-04-07 17:32 [RFA][python] Add program space support Doug Evans
  2010-04-07 17:39 ` Doug Evans
@ 2010-04-07 17:52 ` Eli Zaretskii
  2010-04-08 22:24   ` Doug Evans
  1 sibling, 1 reply; 9+ messages in thread
From: Eli Zaretskii @ 2010-04-07 17:52 UTC (permalink / raw)
  To: Doug Evans; +Cc: gdb-patches

> Date: Wed,  7 Apr 2010 10:32:22 -0700 (PDT)
> From: dje@google.com (Doug Evans)
> 
> This patch adds basic support for program spaces to python.

Thanks.  A few comments to the patch for the manual:

> 	doc/
> 	* gdb.texinfo (Python API): Add progspaces section.
> 	(Selecting Pretty-Printers): Progspace pretty-printers are
> 	searched too.

This lacks an entry for the new section you added.

> +@node Progspaces In Python
> +@subsubsection Progspaces In Python

It is okay to use shorthands in node names, but for the section name
I'd prefer to use "Program Spaces", the full name.  There's no
requirement for the two to be identical.

> +A program space, or ``progspace'', represents a symbolic view
                       ^^^^^^^^^^^^^
Please use @dfn{progspace} here, it is specifically designed for
introducing new terminology.  It produces the same quoted string in
Info as ``..'', but looks prettier in the printed version.

> +A program space, or ``progspace'', represents a symbolic view
> +of an address space.

An @xref here to where program spaces are described would be useful.

> +@findex gdb.current_progspace
> +@defun current_progspace
> +This function returns the program space of the currently selected inferior.

Is this a function or a method?  If the latter, we have @defmethod to
DTRT.

Okay with those changes.

Thanks.


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

* Re: [RFA][python] Add program space support
  2010-04-07 17:39 ` Doug Evans
@ 2010-04-07 17:54   ` Eli Zaretskii
  0 siblings, 0 replies; 9+ messages in thread
From: Eli Zaretskii @ 2010-04-07 17:54 UTC (permalink / raw)
  To: Doug Evans; +Cc: gdb-patches

> Date: Wed, 7 Apr 2010 10:39:30 -0700
> From: Doug Evans <dje@google.com>
> 
> Blech, forgot a NEWS entry.
> 
> 2010-04-07  Doug Evans  <dje@google.com>
> 
>         * NEWS: Add entry for python program space support.

OK.  Thanks.


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

* Re: [RFA][python] Add program space support
  2010-04-07 17:52 ` Eli Zaretskii
@ 2010-04-08 22:24   ` Doug Evans
  2010-04-09  7:37     ` Eli Zaretskii
  0 siblings, 1 reply; 9+ messages in thread
From: Doug Evans @ 2010-04-08 22:24 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 3172 bytes --]

On Wed, Apr 7, 2010 at 10:52 AM, Eli Zaretskii <eliz@gnu.org> wrote:
>> Date: Wed,  7 Apr 2010 10:32:22 -0700 (PDT)
>> From: dje@google.com (Doug Evans)
>>
>> This patch adds basic support for program spaces to python.
>
> Thanks.  A few comments to the patch for the manual:
>
>>       doc/
>>       * gdb.texinfo (Python API): Add progspaces section.
>>       (Selecting Pretty-Printers): Progspace pretty-printers are
>>       searched too.
>
> This lacks an entry for the new section you added.

Fixed.

>> +@node Progspaces In Python
>> +@subsubsection Progspaces In Python
>
> It is okay to use shorthands in node names, but for the section name
> I'd prefer to use "Program Spaces", the full name.  There's no
> requirement for the two to be identical.

Fixed.

>> +A program space, or ``progspace'', represents a symbolic view
>                       ^^^^^^^^^^^^^
> Please use @dfn{progspace} here, it is specifically designed for
> introducing new terminology.  It produces the same quoted string in
> Info as ``..'', but looks prettier in the printed version.

Fixed.

>> +A program space, or ``progspace'', represents a symbolic view
>> +of an address space.
>
> An @xref here to where program spaces are described would be useful.

There is no existing section describing program spaces and I wouldn't
know what to say beyond what I've already written.
Suggestions?  We *could* leave it as is for now.

>> +@findex gdb.current_progspace
>> +@defun current_progspace
>> +This function returns the program space of the currently selected inferior.
>
> Is this a function or a method?  If the latter, we have @defmethod to
> DTRT.

Function.

> Okay with those changes.
>
> Thanks.

Here is the revised patch.

gdb-patches: I will check this in tomorrow if there are no further objections.

2010-04-08  Doug Evans  <dje@google.com>

        * NEWS: Add entry for python program space support.
        * Makefile.in (SUBDIR_PYTHON_OBS): Add py-progspace.o.
        (SUBDIR_PYTHON_SRCS): Add py-progspace.c.
        (py-progspace.o): New rule.
        * python/py-prettyprint.c (find_pretty_printer_from_objfiles): New
        function.
        (find_pretty_printer_from_progspace): New function.
        (find_pretty_printer_from_gdb): New function.
        (find_pretty_printer): Rewrite.
        * python/py-progspace.c: New file.
        * python/python-internal.h (program_space): Add forward decl.
        (pspace_to_pspace_object, pspy_get_printers): Declare.
        (gdbpy_initialize_pspace): Declare.
        * python/python.c: #include "progspace.h".
        (gdbpy_get_current_progspace, gdbpy_progspaces): New functions.
        (_initialize_python): Call gdbpy_initialize_pspace.
        (GdbMethods): Add current_progspace, progspaces.

        doc/
        * gdb.texinfo (Python API): Add progspaces section.
        (Selecting Pretty-Printers): Progspace pretty-printers are
        searched too.
        (Progspaces In Python): New section.

        testsuite/
        * gdb.python/py-progspace.c: New file.
        * gdb.python/py-progspace.exp: New file.

[-- Attachment #2: gdb-100408-python-progspace-2.patch.txt --]
[-- Type: text/plain, Size: 25352 bytes --]

2010-04-07  Doug Evans  <dje@google.com>

	* NEWS: Add entry for python program space support.
	* Makefile.in (SUBDIR_PYTHON_OBS): Add py-progspace.o.
	(SUBDIR_PYTHON_SRCS): Add py-progspace.c.
	(py-progspace.o): New rule.
	* python/py-prettyprint.c (find_pretty_printer_from_objfiles): New
	function.
	(find_pretty_printer_from_progspace): New function.
	(find_pretty_printer_from_gdb): New function.
	(find_pretty_printer): Rewrite.
	* python/py-progspace.c: New file.
	* python/python-internal.h (program_space): Add forward decl.
	(pspace_to_pspace_object, pspy_get_printers): Declare.
	(gdbpy_initialize_pspace): Declare.
	* python/python.c: #include "progspace.h".
	(gdbpy_get_current_progspace, gdbpy_progspaces): New functions.
	(_initialize_python): Call gdbpy_initialize_pspace.
	(GdbMethods): Add current_progspace, progspaces.

	doc/
	* gdb.texinfo (Python API): Add progspaces section.
	(Selecting Pretty-Printers): Progspace pretty-printers are
	searched too.
	(Progspaces In Python): New section.

	testsuite/
	* gdb.python/py-progspace.c: New file.
	* gdb.python/py-progspace.exp: New file.

Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.1116
diff -u -p -r1.1116 Makefile.in
--- Makefile.in	23 Mar 2010 21:31:29 -0000	1.1116
+++ Makefile.in	8 Apr 2010 21:42:31 -0000
@@ -274,6 +274,7 @@ SUBDIR_PYTHON_OBS = \
 	py-lazy-string.o \
 	py-objfile.o \
 	py-prettyprint.o \
+	py-progspace.o \
 	py-symbol.o \
 	py-symtab.o \
 	py-type.o \
@@ -288,6 +289,7 @@ SUBDIR_PYTHON_SRCS = \
 	python/py-lazy-string.c \
 	python/py-objfile.c \
 	python/py-prettyprint.c \
+	python/py-progspace.c \
 	python/py-symbol.c \
 	python/py-symtab.c \
 	python/py-type.c \
@@ -2010,6 +2012,10 @@ py-prettyprint.o: $(srcdir)/python/py-pr
 	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-prettyprint.c
 	$(POSTCOMPILE)
 
+py-progspace.o: $(srcdir)/python/py-progspace.c
+	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-progspace.c
+	$(POSTCOMPILE)
+
 py-symbol.o: $(srcdir)/python/py-symbol.c
 	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-symbol.c
 	$(POSTCOMPILE)
Index: NEWS
===================================================================
RCS file: /cvs/src/src/gdb/NEWS,v
retrieving revision 1.367
diff -u -p -r1.367 NEWS
--- NEWS	1 Apr 2010 14:11:22 -0000	1.367
+++ NEWS	8 Apr 2010 21:42:31 -0000
@@ -25,10 +25,13 @@
 
 * Python scripting
 
-** The GDB Python API now has access to symbols, symbol tables, and
-   frame's code blocks.
+** The GDB Python API now has access to program spaces, symbols,
+   symbol tables, and frame's code blocks.
 
-** New methods gdb.target_charset and gdb.target_wide_charset.
+** New functions gdb.target_charset, gdb.target_wide_charset,
+   gdb.progspaces, and gdb.current_progspace.
+
+** Pretty-printers are now also looked up in the current program space.
 
 * Tracepoint actions were unified with breakpoint commands. In particular,
 there are no longer differences in "info break" output for breakpoints and
Index: doc/gdb.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
retrieving revision 1.697
diff -u -p -r1.697 gdb.texinfo
--- doc/gdb.texinfo	8 Apr 2010 21:08:40 -0000	1.697
+++ doc/gdb.texinfo	8 Apr 2010 21:42:31 -0000
@@ -19708,6 +19708,7 @@ situation, a Python @code{KeyboardInterr
 * Selecting Pretty-Printers::   How GDB chooses a pretty-printer.
 * Commands In Python::          Implementing new commands in Python.
 * Functions In Python::         Writing new convenience functions.
+* Progspaces In Python::        Program spaces.
 * Objfiles In Python::          Object files.
 * Frames In Python::            Accessing inferior stack frames from Python.
 * Blocks In Python::            Accessing frame blocks from Python.
@@ -20436,6 +20437,7 @@ If the result is not one of these types,
 
 The Python list @code{gdb.pretty_printers} contains an array of
 functions that have been registered via addition as a pretty-printer.
+Each @code{gdb.Progspace} contains a @code{pretty_printers} attribute.
 Each @code{gdb.Objfile} also contains a @code{pretty_printers}
 attribute.
 
@@ -20446,8 +20448,12 @@ cannot create a pretty-printer for the v
 @code{None}.
 
 @value{GDBN} first checks the @code{pretty_printers} attribute of each
-@code{gdb.Objfile} and iteratively calls each function in the list for
-that @code{gdb.Objfile} until it receives a pretty-printer object.
+@code{gdb.Objfile} in the current program space and iteratively calls
+each function in the list for that @code{gdb.Objfile} until it receives
+a pretty-printer object.
+If no pretty-printer is found in the objfile lists, @value{GDBN} then
+searches the pretty-printer list of the current program space,
+calling each function until an object is returned.
 After these lists have been exhausted, it tries the global
 @code{gdb.pretty-printers} list, again calling each function until an
 object is returned.
@@ -20845,6 +20851,47 @@ registration of the function with @value
 Python code is read into @value{GDBN}, you may need to import the
 @code{gdb} module explicitly.
 
+@node Progspaces In Python
+@subsubsection Program Spaces In Python
+
+@cindex progspaces in python
+@tindex gdb.Progspace
+@tindex Progspace
+A program space, or @dfn{progspace}, represents a symbolic view
+of an address space.
+It consists of all of the objfiles of the program.
+@xref{Objfiles In Python}.
+
+The following progspace-related functions are available in the
+@code{gdb} module:
+
+@findex gdb.current_progspace
+@defun current_progspace
+This function returns the program space of the currently selected inferior.
+@xref{Inferiors and Programs}.
+@end defun
+
+@findex gdb.progspaces
+@defun progspaces
+Return a sequence of all the progspaces currently known to @value{GDBN}.
+@end defun
+
+Each progspace is represented by an instance of the @code{gdb.Progspace}
+class.
+
+@defivar Progspace filename
+The file name of the progspace as a string.
+@end defivar
+
+@defivar Progspace pretty_printers
+The @code{pretty_printers} attribute is a list of functions.  It is
+used to look up pretty-printers.  A @code{Value} is passed to each
+function in order; if the function returns @code{None}, then the
+search continues.  Otherwise, the return value should be an object
+which is used to format the value.  @xref{Pretty Printing}, for more
+information.
+@end defivar
+
 @node Objfiles In Python
 @subsubsection Objfiles In Python
 
Index: python/py-prettyprint.c
===================================================================
RCS file: /cvs/src/src/gdb/python/py-prettyprint.c,v
retrieving revision 1.5
diff -u -p -r1.5 py-prettyprint.c
--- python/py-prettyprint.c	2 Feb 2010 16:45:16 -0000	1.5
+++ python/py-prettyprint.c	8 Apr 2010 21:42:31 -0000
@@ -29,12 +29,12 @@
 #ifdef HAVE_PYTHON
 #include "python-internal.h"
 
-
 /* Helper function for find_pretty_printer which iterates over a list,
    calls each function and inspects output.  This will return a
    printer object if one recognizes VALUE.  If no printer is found, it
    will return None.  On error, it will set the Python error and
    return NULL.  */
+
 static PyObject *
 search_pp_list (PyObject *list, PyObject *value)
 {
@@ -60,18 +60,19 @@ search_pp_list (PyObject *list, PyObject
   Py_RETURN_NONE;
 }
 
-/* Find the pretty-printing constructor function for VALUE.  If no
-   pretty-printer exists, return None.  If one exists, return a new
-   reference.  On error, set the Python error and return NULL.  */
+/* Subroutine of find_pretty_printer to simplify it.
+   Look for a pretty-printer to print VALUE in all objfiles.
+   The result is NULL if there's an error and the search should be terminated.
+   The result is Py_None, suitably inc-ref'd, if no pretty-printer was found.
+   Otherwise the result is the pretty-printer function, suitably inc-ref'd.  */
+
 static PyObject *
-find_pretty_printer (PyObject *value)
+find_pretty_printer_from_objfiles (PyObject *value)
 {
-  PyObject *pp_list = NULL;
-  PyObject *function = NULL;
+  PyObject *pp_list;
+  PyObject *function;
   struct objfile *obj;
-  volatile struct gdb_exception except;
 
-  /* Look at the pretty-printer dictionary for each objfile.  */
   ALL_OBJFILES (obj)
   {
     PyObject *objf = objfile_to_objfile_object (obj);
@@ -84,44 +85,95 @@ find_pretty_printer (PyObject *value)
 
     pp_list = objfpy_get_printers (objf, NULL);
     function = search_pp_list (pp_list, value);
+    Py_XDECREF (pp_list);
 
-    /* If there is an error in any objfile list, abort the search and
-       exit.  */
+    /* If there is an error in any objfile list, abort the search and exit.  */
     if (! function)
-      {
-	Py_XDECREF (pp_list);
-	return NULL;
-      }
+      return NULL;
 
     if (function != Py_None)
-      goto done;
+      return function;
     
     Py_DECREF (function);
-    Py_XDECREF (pp_list);
   }
 
-  pp_list = NULL;
+  Py_RETURN_NONE;
+}
+
+/* Subroutine of find_pretty_printer to simplify it.
+   Look for a pretty-printer to print VALUE in the current program space.
+   The result is NULL if there's an error and the search should be terminated.
+   The result is Py_None, suitably inc-ref'd, if no pretty-printer was found.
+   Otherwise the result is the pretty-printer function, suitably inc-ref'd.  */
+
+static PyObject *
+find_pretty_printer_from_progspace (PyObject *value)
+{
+  PyObject *pp_list;
+  PyObject *function;
+  PyObject *obj = pspace_to_pspace_object (current_program_space);
+
+  if (!obj)
+    return NULL;
+  pp_list = pspy_get_printers (obj, NULL);
+  function = search_pp_list (pp_list, value);
+  Py_XDECREF (pp_list);
+  return function;
+}
+
+/* Subroutine of find_pretty_printer to simplify it.
+   Look for a pretty-printer to print VALUE in the gdb module.
+   The result is NULL if there's an error and the search should be terminated.
+   The result is Py_None, suitably inc-ref'd, if no pretty-printer was found.
+   Otherwise the result is the pretty-printer function, suitably inc-ref'd.  */
+
+static PyObject *
+find_pretty_printer_from_gdb (PyObject *value)
+{
+  PyObject *pp_list;
+  PyObject *function;
+
   /* Fetch the global pretty printer dictionary.  */
   if (! PyObject_HasAttrString (gdb_module, "pretty_printers"))
+    Py_RETURN_NONE;
+  pp_list = PyObject_GetAttrString (gdb_module, "pretty_printers");
+  if (pp_list == NULL || ! PyList_Check (pp_list))
     {
-      function = Py_None;
-      Py_INCREF (function);
-      goto done;
+      Py_XDECREF (pp_list);
+      Py_RETURN_NONE;
     }
-  pp_list = PyObject_GetAttrString (gdb_module, "pretty_printers");
-  if (! pp_list)
-    goto done;
-  if (! PyList_Check (pp_list))
-    goto done;
 
   function = search_pp_list (pp_list, value);
-
- done:
   Py_XDECREF (pp_list);
-  
   return function;
 }
 
+/* Find the pretty-printing constructor function for VALUE.  If no
+   pretty-printer exists, return None.  If one exists, return a new
+   reference.  On error, set the Python error and return NULL.  */
+
+static PyObject *
+find_pretty_printer (PyObject *value)
+{
+  PyObject *function;
+
+  /* Look at the pretty-printer dictionary for each objfile
+     in the current program-space.  */
+  function = find_pretty_printer_from_objfiles (value);
+  if (function == NULL || function != Py_None)
+    return function;
+  Py_DECREF (function);
+
+  /* Look at the pretty-printer dictionary for the current program-space.  */
+  function = find_pretty_printer_from_progspace (value);
+  if (function == NULL || function != Py_None)
+    return function;
+  Py_DECREF (function);
+
+  /* Look at the pretty-printer dictionary in the gdb module.  */
+  function = find_pretty_printer_from_gdb (value);
+  return function;
+}
 
 /* Pretty-print a single value, via the printer object PRINTER.
    If the function returns a string, a PyObject containing the string
Index: python/py-progspace.c
===================================================================
RCS file: python/py-progspace.c
diff -N python/py-progspace.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ python/py-progspace.c	8 Apr 2010 21:42:31 -0000
@@ -0,0 +1,240 @@
+/* Python interface to program spaces.
+
+   Copyright (C) 2010 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include "defs.h"
+#include "python-internal.h"
+#include "charset.h"
+#include "progspace.h"
+#include "objfiles.h"
+#include "language.h"
+
+typedef struct
+{
+  PyObject_HEAD
+
+  /* The corresponding pspace.  */
+  struct program_space *pspace;
+
+  /* The pretty-printer list of functions.  */
+  PyObject *printers;
+} pspace_object;
+
+static PyTypeObject pspace_object_type;
+
+static const struct program_space_data *pspy_pspace_data_key;
+
+\f
+
+/* An Objfile method which returns the objfile's file name, or None.  */
+
+static PyObject *
+pspy_get_filename (PyObject *self, void *closure)
+{
+  pspace_object *obj = (pspace_object *) self;
+  if (obj->pspace)
+    {
+      struct objfile *objfile = obj->pspace->symfile_object_file;
+      if (objfile && objfile->name)
+	return PyString_Decode (objfile->name, strlen (objfile->name),
+				host_charset (), NULL);
+    }
+  Py_RETURN_NONE;
+}
+
+static void
+pspy_dealloc (PyObject *self)
+{
+  pspace_object *ps_self = (pspace_object *) self;
+  Py_XDECREF (ps_self->printers);
+  self->ob_type->tp_free (self);
+}
+
+static PyObject *
+pspy_new (PyTypeObject *type, PyObject *args, PyObject *keywords)
+{
+  pspace_object *self = (pspace_object *) type->tp_alloc (type, 0);
+  if (self)
+    {
+      self->pspace = NULL;
+
+      self->printers = PyList_New (0);
+      if (!self->printers)
+	{
+	  Py_DECREF (self);
+	  return NULL;
+	}
+    }
+  return (PyObject *) self;
+}
+
+PyObject *
+pspy_get_printers (PyObject *o, void *ignore)
+{
+  pspace_object *self = (pspace_object *) o;
+  Py_INCREF (self->printers);
+  return self->printers;
+}
+
+static int
+pspy_set_printers (PyObject *o, PyObject *value, void *ignore)
+{
+  PyObject *tmp;
+  pspace_object *self = (pspace_object *) o;
+  if (! value)
+    {
+      PyErr_SetString (PyExc_TypeError,
+		       "cannot delete the pretty_printers attribute");
+      return -1;
+    }
+
+  if (! PyList_Check (value))
+    {
+      PyErr_SetString (PyExc_TypeError,
+		       "the pretty_printers attribute must be a list");
+      return -1;
+    }
+
+  /* Take care in case the LHS and RHS are related somehow.  */
+  tmp = self->printers;
+  Py_INCREF (value);
+  self->printers = value;
+  Py_XDECREF (tmp);
+
+  return 0;
+}
+
+\f
+
+/* Clear the PSPACE pointer in a Pspace object and remove the reference.  */
+
+static void
+py_free_pspace (struct program_space *pspace, void *datum)
+{
+  struct cleanup *cleanup;
+  pspace_object *object = datum;
+  /* FIXME: What's the right way to get a program space's arch?
+     There may be multiple.  */
+  struct gdbarch *arch = get_objfile_arch (pspace->symfile_object_file);
+
+  cleanup = ensure_python_env (arch, current_language);
+  object->pspace = NULL;
+  Py_DECREF ((PyObject *) object);
+  do_cleanups (cleanup);
+}
+
+/* Return a borrowed reference to the Python object of type Pspace
+   representing PSPACE.  If the object has already been created,
+   return it.  Otherwise, create it.  Return NULL and set the Python
+   error on failure.  */
+
+PyObject *
+pspace_to_pspace_object (struct program_space *pspace)
+{
+  pspace_object *object;
+
+  object = program_space_data (pspace, pspy_pspace_data_key);
+  if (!object)
+    {
+      object = PyObject_New (pspace_object, &pspace_object_type);
+      if (object)
+	{
+	  PyObject *dict;
+
+	  object->pspace = pspace;
+
+	  object->printers = PyList_New (0);
+	  if (!object->printers)
+	    {
+	      Py_DECREF (object);
+	      return NULL;
+	    }
+
+	  set_program_space_data (pspace, pspy_pspace_data_key, object);
+	}
+    }
+
+  return (PyObject *) object;
+}
+
+void
+gdbpy_initialize_pspace (void)
+{
+  pspy_pspace_data_key
+    = register_program_space_data_with_cleanup (py_free_pspace);
+
+  if (PyType_Ready (&pspace_object_type) < 0)
+    return;
+
+  Py_INCREF (&pspace_object_type);
+  PyModule_AddObject (gdb_module, "Progspace", (PyObject *) &pspace_object_type);
+}
+
+\f
+
+static PyGetSetDef pspace_getset[] =
+{
+  { "filename", pspy_get_filename, NULL,
+    "The progspace's main filename, or None.", NULL },
+  { "pretty_printers", pspy_get_printers, pspy_set_printers,
+    "Pretty printers.", NULL },
+  { NULL }
+};
+
+static PyTypeObject pspace_object_type =
+{
+  PyObject_HEAD_INIT (NULL)
+  0,				  /*ob_size*/
+  "gdb.Progspace",		  /*tp_name*/
+  sizeof (pspace_object),	  /*tp_basicsize*/
+  0,				  /*tp_itemsize*/
+  pspy_dealloc,			  /*tp_dealloc*/
+  0,				  /*tp_print*/
+  0,				  /*tp_getattr*/
+  0,				  /*tp_setattr*/
+  0,				  /*tp_compare*/
+  0,				  /*tp_repr*/
+  0,				  /*tp_as_number*/
+  0,				  /*tp_as_sequence*/
+  0,				  /*tp_as_mapping*/
+  0,				  /*tp_hash */
+  0,				  /*tp_call*/
+  0,				  /*tp_str*/
+  0,				  /*tp_getattro*/
+  0,				  /*tp_setattro*/
+  0,				  /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT,		  /*tp_flags*/
+  "GDB progspace object",	  /* tp_doc */
+  0,				  /* tp_traverse */
+  0,				  /* tp_clear */
+  0,				  /* tp_richcompare */
+  0,				  /* tp_weaklistoffset */
+  0,				  /* tp_iter */
+  0,				  /* tp_iternext */
+  0,				  /* tp_methods */
+  0,				  /* tp_members */
+  pspace_getset,		  /* tp_getset */
+  0,				  /* tp_base */
+  0,				  /* tp_dict */
+  0,				  /* tp_descr_get */
+  0,				  /* tp_descr_set */
+  0,				  /* tp_dictoffset */
+  0,				  /* tp_init */
+  0,				  /* tp_alloc */
+  pspy_new,			  /* tp_new */
+};
Index: python/python-internal.h
===================================================================
RCS file: /cvs/src/src/gdb/python/python-internal.h,v
retrieving revision 1.22
diff -u -p -r1.22 python-internal.h
--- python/python-internal.h	9 Mar 2010 17:12:40 -0000	1.22
+++ python/python-internal.h	8 Apr 2010 21:42:31 -0000
@@ -68,6 +68,7 @@ typedef int Py_ssize_t;
 struct block;
 struct value;
 struct language_defn;
+struct program_space;
 
 extern PyObject *gdb_module;
 extern PyTypeObject value_object_type;
@@ -89,8 +90,11 @@ PyObject *symbol_to_symbol_object (struc
 PyObject *block_to_block_object (struct block *block, struct objfile *objfile);
 PyObject *value_to_value_object (struct value *v);
 PyObject *type_to_type_object (struct type *);
-PyObject *objfile_to_objfile_object (struct objfile *);
 
+PyObject *pspace_to_pspace_object (struct program_space *);
+PyObject *pspy_get_printers (PyObject *, void *);
+
+PyObject *objfile_to_objfile_object (struct objfile *);
 PyObject *objfpy_get_printers (PyObject *, void *);
 
 struct block *block_object_to_block (PyObject *obj);
@@ -110,6 +114,7 @@ void gdbpy_initialize_symtabs (void);
 void gdbpy_initialize_blocks (void);
 void gdbpy_initialize_types (void);
 void gdbpy_initialize_functions (void);
+void gdbpy_initialize_pspace (void);
 void gdbpy_initialize_objfile (void);
 void gdbpy_initialize_lazy_string (void);
 
Index: python/python.c
===================================================================
RCS file: /cvs/src/src/gdb/python/python.c,v
retrieving revision 1.28
diff -u -p -r1.28 python.c
--- python/python.c	8 Apr 2010 04:57:25 -0000	1.28
+++ python/python.c	8 Apr 2010 21:42:31 -0000
@@ -23,6 +23,7 @@
 #include "ui-out.h"
 #include "cli/cli-script.h"
 #include "gdbcmd.h"
+#include "progspace.h"
 #include "objfiles.h"
 #include "observer.h"
 #include "value.h"
@@ -415,6 +416,47 @@ gdbpy_print_stack (void)
 
 \f
 
+/* Return the current Progspace.
+   There always is one.  */
+
+static PyObject *
+gdbpy_get_current_progspace (PyObject *unused1, PyObject *unused2)
+{
+  PyObject *result;
+
+  result = pspace_to_pspace_object (current_program_space);
+  if (result)
+    Py_INCREF (result);
+  return result;
+}
+
+/* Return a sequence holding all the Progspaces.  */
+
+static PyObject *
+gdbpy_progspaces (PyObject *unused1, PyObject *unused2)
+{
+  struct program_space *ps;
+  PyObject *list;
+
+  list = PyList_New (0);
+  if (!list)
+    return NULL;
+
+  ALL_PSPACES (ps)
+  {
+    PyObject *item = pspace_to_pspace_object (ps);
+    if (!item || PyList_Append (list, item) == -1)
+      {
+	Py_DECREF (list);
+	return NULL;
+      }
+  }
+
+  return list;
+}
+
+\f
+
 /* The "current" objfile.  This is set when gdb detects that a new
    objfile has been loaded.  It is only set for the duration of a call
    to gdbpy_new_objfile; it is NULL at other times.  */
@@ -510,6 +552,7 @@ gdbpy_get_current_objfile (PyObject *unu
 }
 
 /* Return a sequence holding all the Objfiles.  */
+
 static PyObject *
 gdbpy_objfiles (PyObject *unused1, PyObject *unused2)
 {
@@ -667,6 +716,7 @@ Enables or disables auto-loading of Pyth
   gdbpy_initialize_blocks ();
   gdbpy_initialize_functions ();
   gdbpy_initialize_types ();
+  gdbpy_initialize_pspace ();
   gdbpy_initialize_objfile ();
   gdbpy_initialize_lazy_string ();
 
@@ -729,6 +779,11 @@ static PyMethodDef GdbMethods[] =
   { "default_visualizer", gdbpy_default_visualizer, METH_VARARGS,
     "Find the default visualizer for a Value." },
 
+  { "current_progspace", gdbpy_get_current_progspace, METH_NOARGS,
+    "Return the current Progspace." },
+  { "progspaces", gdbpy_progspaces, METH_NOARGS,
+    "Return a sequence of all progspaces." },
+
   { "current_objfile", gdbpy_get_current_objfile, METH_NOARGS,
     "Return the current Objfile being loaded, or None." },
   { "objfiles", gdbpy_objfiles, METH_NOARGS,
Index: testsuite/gdb.python/py-progspace.c
===================================================================
RCS file: testsuite/gdb.python/py-progspace.c
diff -N testsuite/gdb.python/py-progspace.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.python/py-progspace.c	8 Apr 2010 21:42:31 -0000
@@ -0,0 +1,22 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2010 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+int
+main ()
+{
+  return 0;
+}
Index: testsuite/gdb.python/py-progspace.exp
===================================================================
RCS file: testsuite/gdb.python/py-progspace.exp
diff -N testsuite/gdb.python/py-progspace.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.python/py-progspace.exp	8 Apr 2010 21:42:31 -0000
@@ -0,0 +1,47 @@
+# Copyright (C) 2010 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# This file is part of the GDB testsuite.  It tests the program space
+# support in Python.
+
+if $tracelevel then {
+    strace $tracelevel
+}
+
+set testfile "py-progspace"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+    untested "Couldn't compile ${srcfile}"
+    return -1
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+# Skip all tests if Python scripting is not enabled.
+if { [skip_python_tests] } { continue }
+
+gdb_test "python print gdb.current_progspace().filename" "None" \
+  "current progspace filename (None)"
+gdb_test "python print gdb.progspaces()" "\\\[<gdb.Progspace object at $hex>\\\]"
+
+gdb_load ${binfile}
+
+gdb_test "python print gdb.current_progspace().filename" "py-progspace" \
+  "current progspace filename (py-progspace)"

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

* Re: [RFA][python] Add program space support
  2010-04-08 22:24   ` Doug Evans
@ 2010-04-09  7:37     ` Eli Zaretskii
  2010-04-09 15:34       ` Doug Evans
  0 siblings, 1 reply; 9+ messages in thread
From: Eli Zaretskii @ 2010-04-09  7:37 UTC (permalink / raw)
  To: Doug Evans; +Cc: gdb-patches

> Date: Thu, 8 Apr 2010 15:24:32 -0700
> From: Doug Evans <dje@google.com>
> Cc: gdb-patches@sourceware.org
> 
> >> +A program space, or ``progspace'', represents a symbolic view
> >> +of an address space.
> >
> > An @xref here to where program spaces are described would be useful.
> 
> There is no existing section describing program spaces and I wouldn't
> know what to say beyond what I've already written.
> Suggestions?  We *could* leave it as is for now.

I didn't ask for you to explain again what program spaces are.  I
asked for a cross-reference to the place where they are already
explained.  Like this:

  @xref{Inferiors and Programs, program spaces}, for more details
  about program spaces.

Thanks.


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

* Re: [RFA][python] Add program space support
  2010-04-09  7:37     ` Eli Zaretskii
@ 2010-04-09 15:34       ` Doug Evans
  2010-04-09 15:42         ` Pedro Alves
  0 siblings, 1 reply; 9+ messages in thread
From: Doug Evans @ 2010-04-09 15:34 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: gdb-patches

On Fri, Apr 9, 2010 at 12:36 AM, Eli Zaretskii <eliz@gnu.org> wrote:
>> Date: Thu, 8 Apr 2010 15:24:32 -0700
>> From: Doug Evans <dje@google.com>
>> Cc: gdb-patches@sourceware.org
>>
>> >> +A program space, or ``progspace'', represents a symbolic view
>> >> +of an address space.
>> >
>> > An @xref here to where program spaces are described would be useful.
>>
>> There is no existing section describing program spaces and I wouldn't
>> know what to say beyond what I've already written.
>> Suggestions?  We *could* leave it as is for now.
>
> I didn't ask for you to explain again what program spaces are.  I
> asked for a cross-reference to the place where they are already
> explained.  Like this:
>
>  @xref{Inferiors and Programs, program spaces}, for more details
>  about program spaces.
>
> Thanks.
>

I guess I misunderstood.  I grepped all of gdb.texinfo, including that
particular xref, and saw nothing that would satisfy "where program
spaces are described" (or explained).
Plus the only reference to program spaces in that particular xref is
inside the description of a "maint" command - "[...], when debugging
GDB itself, ...".  It didn't seem kosher to refer users to sections
intended for GDB developers.  But no matter, learn something new every
day.
Thanks.


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

* Re: [RFA][python] Add program space support
  2010-04-09 15:34       ` Doug Evans
@ 2010-04-09 15:42         ` Pedro Alves
  2010-04-14 22:47           ` Doug Evans
  0 siblings, 1 reply; 9+ messages in thread
From: Pedro Alves @ 2010-04-09 15:42 UTC (permalink / raw)
  To: gdb-patches; +Cc: Doug Evans, Eli Zaretskii

On Friday 09 April 2010 16:34:11, Doug Evans wrote:
> I guess I misunderstood.  I grepped all of gdb.texinfo, including that
> particular xref, and saw nothing that would satisfy "where program
> spaces are described" (or explained).

Because they're not visible to the user in any way.  It's all exposed
through inferiors.

-- 
Pedro Alves


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

* Re: [RFA][python] Add program space support
  2010-04-09 15:42         ` Pedro Alves
@ 2010-04-14 22:47           ` Doug Evans
  0 siblings, 0 replies; 9+ messages in thread
From: Doug Evans @ 2010-04-14 22:47 UTC (permalink / raw)
  To: Eli Zaretskii, Pedro Alves; +Cc: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 5743 bytes --]

On Fri, Apr 9, 2010 at 12:36 AM, Eli Zaretskii <eliz@gnu.org> wrote:
> I didn't ask for you to explain again what program spaces are.  I
> asked for a cross-reference to the place where they are already
> explained.  Like this:
>
>  @xref{Inferiors and Programs, program spaces}, for more details
>  about program spaces.

On Fri, Apr 9, 2010 at 8:42 AM, Pedro Alves <pedro@codesourcery.com> wrote:
> On Friday 09 April 2010 16:34:11, Doug Evans wrote:
>> I guess I misunderstood.  I grepped all of gdb.texinfo, including that
>> particular xref, and saw nothing that would satisfy "where program
>> spaces are described" (or explained).
>
> Because they're not visible to the user in any way.  It's all exposed
> through inferiors.

I'm not sure where this leaves us.

I've included the requested xref, and will check in the attached patch
tomorrow if there are no objections.

For reference sake, here's the doc patch.

Index: doc/gdb.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
retrieving revision 1.704
diff -u -p -r1.704 gdb.texinfo
--- doc/gdb.texinfo	14 Apr 2010 12:02:44 -0000	1.704
+++ doc/gdb.texinfo	14 Apr 2010 22:34:36 -0000
@@ -19708,6 +19708,7 @@ situation, a Python @code{KeyboardInterr
 * Selecting Pretty-Printers::   How GDB chooses a pretty-printer.
 * Commands In Python::          Implementing new commands in Python.
 * Functions In Python::         Writing new convenience functions.
+* Progspaces In Python::        Program spaces.
 * Objfiles In Python::          Object files.
 * Frames In Python::            Accessing inferior stack frames from Python.
 * Blocks In Python::            Accessing frame blocks from Python.
@@ -20446,6 +20447,7 @@ If the result is not one of these types,

 The Python list @code{gdb.pretty_printers} contains an array of
 functions that have been registered via addition as a pretty-printer.
+Each @code{gdb.Progspace} contains a @code{pretty_printers} attribute.
 Each @code{gdb.Objfile} also contains a @code{pretty_printers}
 attribute.

@@ -20456,8 +20458,12 @@ cannot create a pretty-printer for the v
 @code{None}.

 @value{GDBN} first checks the @code{pretty_printers} attribute of each
-@code{gdb.Objfile} and iteratively calls each function in the list for
-that @code{gdb.Objfile} until it receives a pretty-printer object.
+@code{gdb.Objfile} in the current program space and iteratively calls
+each function in the list for that @code{gdb.Objfile} until it receives
+a pretty-printer object.
+If no pretty-printer is found in the objfile lists, @value{GDBN} then
+searches the pretty-printer list of the current program space,
+calling each function until an object is returned.
 After these lists have been exhausted, it tries the global
 @code{gdb.pretty-printers} list, again calling each function until an
 object is returned.
@@ -20855,6 +20861,49 @@ registration of the function with @value
 Python code is read into @value{GDBN}, you may need to import the
 @code{gdb} module explicitly.

+@node Progspaces In Python
+@subsubsection Program Spaces In Python
+
+@cindex progspaces in python
+@tindex gdb.Progspace
+@tindex Progspace
+A program space, or @dfn{progspace}, represents a symbolic view
+of an address space.
+It consists of all of the objfiles of the program.
+@xref{Objfiles In Python}.
+@xref{Inferiors and Programs, program spaces}, for more details
+about program spaces.
+
+The following progspace-related functions are available in the
+@code{gdb} module:
+
+@findex gdb.current_progspace
+@defun current_progspace
+This function returns the program space of the currently selected inferior.
+@xref{Inferiors and Programs}.
+@end defun
+
+@findex gdb.progspaces
+@defun progspaces
+Return a sequence of all the progspaces currently known to @value{GDBN}.
+@end defun
+
+Each progspace is represented by an instance of the @code{gdb.Progspace}
+class.
+
+@defivar Progspace filename
+The file name of the progspace as a string.
+@end defivar
+
+@defivar Progspace pretty_printers
+The @code{pretty_printers} attribute is a list of functions.  It is
+used to look up pretty-printers.  A @code{Value} is passed to each
+function in order; if the function returns @code{None}, then the
+search continues.  Otherwise, the return value should be an object
+which is used to format the value.  @xref{Pretty Printing}, for more
+information.
+@end defivar
+
 @node Objfiles In Python
 @subsubsection Objfiles In Python


---

2010-04-14  Doug Evans  <dje@google.com>

	* NEWS: Add entry for python program space support.
	* Makefile.in (SUBDIR_PYTHON_OBS): Add py-progspace.o.
	(SUBDIR_PYTHON_SRCS): Add py-progspace.c.
	(py-progspace.o): New rule.
	* python/py-prettyprint.c (find_pretty_printer_from_objfiles): New
	function.
	(find_pretty_printer_from_progspace): New function.
	(find_pretty_printer_from_gdb): New function.
	(find_pretty_printer): Rewrite.
	* python/py-progspace.c: New file.
	* python/python-internal.h (program_space): Add forward decl.
	(pspace_to_pspace_object, pspy_get_printers): Declare.
	(gdbpy_initialize_pspace): Declare.
	* python/python.c: #include "progspace.h".
	(gdbpy_get_current_progspace, gdbpy_progspaces): New functions.
	(_initialize_python): Call gdbpy_initialize_pspace.
	(GdbMethods): Add current_progspace, progspaces.

	doc/
	* gdb.texinfo (Python API): Add progspaces section.
	(Selecting Pretty-Printers): Progspace pretty-printers are
	searched too.
	(Progspaces In Python): New section.

	testsuite/
	* gdb.python/py-progspace.c: New file.
	* gdb.python/py-progspace.exp: New file.

[-- Attachment #2: gdb-100414-python-progspace-3.patch.txt --]
[-- Type: text/plain, Size: 25479 bytes --]

2010-04-14  Doug Evans  <dje@google.com>

	* NEWS: Add entry for python program space support.
	* Makefile.in (SUBDIR_PYTHON_OBS): Add py-progspace.o.
	(SUBDIR_PYTHON_SRCS): Add py-progspace.c.
	(py-progspace.o): New rule.
	* python/py-prettyprint.c (find_pretty_printer_from_objfiles): New
	function.
	(find_pretty_printer_from_progspace): New function.
	(find_pretty_printer_from_gdb): New function.
	(find_pretty_printer): Rewrite.
	* python/py-progspace.c: New file.
	* python/python-internal.h (program_space): Add forward decl.
	(pspace_to_pspace_object, pspy_get_printers): Declare.
	(gdbpy_initialize_pspace): Declare.
	* python/python.c: #include "progspace.h".
	(gdbpy_get_current_progspace, gdbpy_progspaces): New functions.
	(_initialize_python): Call gdbpy_initialize_pspace.
	(GdbMethods): Add current_progspace, progspaces.

	doc/
	* gdb.texinfo (Python API): Add progspaces section.
	(Selecting Pretty-Printers): Progspace pretty-printers are
	searched too.
	(Progspaces In Python): New section.

	testsuite/
	* gdb.python/py-progspace.c: New file.
	* gdb.python/py-progspace.exp: New file.

Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.1117
diff -u -p -r1.1117 Makefile.in
--- Makefile.in	9 Apr 2010 09:41:42 -0000	1.1117
+++ Makefile.in	14 Apr 2010 22:34:36 -0000
@@ -275,6 +275,7 @@ SUBDIR_PYTHON_OBS = \
 	py-lazy-string.o \
 	py-objfile.o \
 	py-prettyprint.o \
+	py-progspace.o \
 	py-symbol.o \
 	py-symtab.o \
 	py-type.o \
@@ -290,6 +291,7 @@ SUBDIR_PYTHON_SRCS = \
 	python/py-lazy-string.c \
 	python/py-objfile.c \
 	python/py-prettyprint.c \
+	python/py-progspace.c \
 	python/py-symbol.c \
 	python/py-symtab.c \
 	python/py-type.c \
@@ -2016,6 +2018,10 @@ py-prettyprint.o: $(srcdir)/python/py-pr
 	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-prettyprint.c
 	$(POSTCOMPILE)
 
+py-progspace.o: $(srcdir)/python/py-progspace.c
+	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-progspace.c
+	$(POSTCOMPILE)
+
 py-symbol.o: $(srcdir)/python/py-symbol.c
 	$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/py-symbol.c
 	$(POSTCOMPILE)
Index: NEWS
===================================================================
RCS file: /cvs/src/src/gdb/NEWS,v
retrieving revision 1.369
diff -u -p -r1.369 NEWS
--- NEWS	9 Apr 2010 15:26:54 -0000	1.369
+++ NEWS	14 Apr 2010 22:34:36 -0000
@@ -31,9 +31,12 @@
 * Python scripting
 
 ** The GDB Python API now has access to breakpoints, symbols, symbol
-   tables, and frame's code blocks.
+   tables, program spaces, and frame's code blocks.
 
-** New methods gdb.target_charset and gdb.target_wide_charset.
+** New functions gdb.target_charset, gdb.target_wide_charset,
+   gdb.progspaces, and gdb.current_progspace.
+
+** Pretty-printers are now also looked up in the current program space.
 
 * Tracepoint actions were unified with breakpoint commands. In particular,
 there are no longer differences in "info break" output for breakpoints and
Index: doc/gdb.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
retrieving revision 1.704
diff -u -p -r1.704 gdb.texinfo
--- doc/gdb.texinfo	14 Apr 2010 12:02:44 -0000	1.704
+++ doc/gdb.texinfo	14 Apr 2010 22:34:36 -0000
@@ -19708,6 +19708,7 @@ situation, a Python @code{KeyboardInterr
 * Selecting Pretty-Printers::   How GDB chooses a pretty-printer.
 * Commands In Python::          Implementing new commands in Python.
 * Functions In Python::         Writing new convenience functions.
+* Progspaces In Python::        Program spaces.
 * Objfiles In Python::          Object files.
 * Frames In Python::            Accessing inferior stack frames from Python.
 * Blocks In Python::            Accessing frame blocks from Python.
@@ -20446,6 +20447,7 @@ If the result is not one of these types,
 
 The Python list @code{gdb.pretty_printers} contains an array of
 functions that have been registered via addition as a pretty-printer.
+Each @code{gdb.Progspace} contains a @code{pretty_printers} attribute.
 Each @code{gdb.Objfile} also contains a @code{pretty_printers}
 attribute.
 
@@ -20456,8 +20458,12 @@ cannot create a pretty-printer for the v
 @code{None}.
 
 @value{GDBN} first checks the @code{pretty_printers} attribute of each
-@code{gdb.Objfile} and iteratively calls each function in the list for
-that @code{gdb.Objfile} until it receives a pretty-printer object.
+@code{gdb.Objfile} in the current program space and iteratively calls
+each function in the list for that @code{gdb.Objfile} until it receives
+a pretty-printer object.
+If no pretty-printer is found in the objfile lists, @value{GDBN} then
+searches the pretty-printer list of the current program space,
+calling each function until an object is returned.
 After these lists have been exhausted, it tries the global
 @code{gdb.pretty-printers} list, again calling each function until an
 object is returned.
@@ -20855,6 +20861,49 @@ registration of the function with @value
 Python code is read into @value{GDBN}, you may need to import the
 @code{gdb} module explicitly.
 
+@node Progspaces In Python
+@subsubsection Program Spaces In Python
+
+@cindex progspaces in python
+@tindex gdb.Progspace
+@tindex Progspace
+A program space, or @dfn{progspace}, represents a symbolic view
+of an address space.
+It consists of all of the objfiles of the program.
+@xref{Objfiles In Python}.
+@xref{Inferiors and Programs, program spaces}, for more details
+about program spaces.
+
+The following progspace-related functions are available in the
+@code{gdb} module:
+
+@findex gdb.current_progspace
+@defun current_progspace
+This function returns the program space of the currently selected inferior.
+@xref{Inferiors and Programs}.
+@end defun
+
+@findex gdb.progspaces
+@defun progspaces
+Return a sequence of all the progspaces currently known to @value{GDBN}.
+@end defun
+
+Each progspace is represented by an instance of the @code{gdb.Progspace}
+class.
+
+@defivar Progspace filename
+The file name of the progspace as a string.
+@end defivar
+
+@defivar Progspace pretty_printers
+The @code{pretty_printers} attribute is a list of functions.  It is
+used to look up pretty-printers.  A @code{Value} is passed to each
+function in order; if the function returns @code{None}, then the
+search continues.  Otherwise, the return value should be an object
+which is used to format the value.  @xref{Pretty Printing}, for more
+information.
+@end defivar
+
 @node Objfiles In Python
 @subsubsection Objfiles In Python
 
Index: python/py-prettyprint.c
===================================================================
RCS file: /cvs/src/src/gdb/python/py-prettyprint.c,v
retrieving revision 1.7
diff -u -p -r1.7 py-prettyprint.c
--- python/py-prettyprint.c	14 Apr 2010 13:18:54 -0000	1.7
+++ python/py-prettyprint.c	14 Apr 2010 22:34:36 -0000
@@ -29,12 +29,12 @@
 #ifdef HAVE_PYTHON
 #include "python-internal.h"
 
-
 /* Helper function for find_pretty_printer which iterates over a list,
    calls each function and inspects output.  This will return a
    printer object if one recognizes VALUE.  If no printer is found, it
    will return None.  On error, it will set the Python error and
    return NULL.  */
+
 static PyObject *
 search_pp_list (PyObject *list, PyObject *value)
 {
@@ -60,18 +60,19 @@ search_pp_list (PyObject *list, PyObject
   Py_RETURN_NONE;
 }
 
-/* Find the pretty-printing constructor function for VALUE.  If no
-   pretty-printer exists, return None.  If one exists, return a new
-   reference.  On error, set the Python error and return NULL.  */
+/* Subroutine of find_pretty_printer to simplify it.
+   Look for a pretty-printer to print VALUE in all objfiles.
+   The result is NULL if there's an error and the search should be terminated.
+   The result is Py_None, suitably inc-ref'd, if no pretty-printer was found.
+   Otherwise the result is the pretty-printer function, suitably inc-ref'd.  */
+
 static PyObject *
-find_pretty_printer (PyObject *value)
+find_pretty_printer_from_objfiles (PyObject *value)
 {
-  PyObject *pp_list = NULL;
-  PyObject *function = NULL;
+  PyObject *pp_list;
+  PyObject *function;
   struct objfile *obj;
-  volatile struct gdb_exception except;
 
-  /* Look at the pretty-printer dictionary for each objfile.  */
   ALL_OBJFILES (obj)
   {
     PyObject *objf = objfile_to_objfile_object (obj);
@@ -84,44 +85,95 @@ find_pretty_printer (PyObject *value)
 
     pp_list = objfpy_get_printers (objf, NULL);
     function = search_pp_list (pp_list, value);
+    Py_XDECREF (pp_list);
 
-    /* If there is an error in any objfile list, abort the search and
-       exit.  */
+    /* If there is an error in any objfile list, abort the search and exit.  */
     if (! function)
-      {
-	Py_XDECREF (pp_list);
-	return NULL;
-      }
+      return NULL;
 
     if (function != Py_None)
-      goto done;
+      return function;
     
     Py_DECREF (function);
-    Py_XDECREF (pp_list);
   }
 
-  pp_list = NULL;
+  Py_RETURN_NONE;
+}
+
+/* Subroutine of find_pretty_printer to simplify it.
+   Look for a pretty-printer to print VALUE in the current program space.
+   The result is NULL if there's an error and the search should be terminated.
+   The result is Py_None, suitably inc-ref'd, if no pretty-printer was found.
+   Otherwise the result is the pretty-printer function, suitably inc-ref'd.  */
+
+static PyObject *
+find_pretty_printer_from_progspace (PyObject *value)
+{
+  PyObject *pp_list;
+  PyObject *function;
+  PyObject *obj = pspace_to_pspace_object (current_program_space);
+
+  if (!obj)
+    return NULL;
+  pp_list = pspy_get_printers (obj, NULL);
+  function = search_pp_list (pp_list, value);
+  Py_XDECREF (pp_list);
+  return function;
+}
+
+/* Subroutine of find_pretty_printer to simplify it.
+   Look for a pretty-printer to print VALUE in the gdb module.
+   The result is NULL if there's an error and the search should be terminated.
+   The result is Py_None, suitably inc-ref'd, if no pretty-printer was found.
+   Otherwise the result is the pretty-printer function, suitably inc-ref'd.  */
+
+static PyObject *
+find_pretty_printer_from_gdb (PyObject *value)
+{
+  PyObject *pp_list;
+  PyObject *function;
+
   /* Fetch the global pretty printer dictionary.  */
   if (! PyObject_HasAttrString (gdb_module, "pretty_printers"))
+    Py_RETURN_NONE;
+  pp_list = PyObject_GetAttrString (gdb_module, "pretty_printers");
+  if (pp_list == NULL || ! PyList_Check (pp_list))
     {
-      function = Py_None;
-      Py_INCREF (function);
-      goto done;
+      Py_XDECREF (pp_list);
+      Py_RETURN_NONE;
     }
-  pp_list = PyObject_GetAttrString (gdb_module, "pretty_printers");
-  if (! pp_list)
-    goto done;
-  if (! PyList_Check (pp_list))
-    goto done;
 
   function = search_pp_list (pp_list, value);
-
- done:
   Py_XDECREF (pp_list);
-  
   return function;
 }
 
+/* Find the pretty-printing constructor function for VALUE.  If no
+   pretty-printer exists, return None.  If one exists, return a new
+   reference.  On error, set the Python error and return NULL.  */
+
+static PyObject *
+find_pretty_printer (PyObject *value)
+{
+  PyObject *function;
+
+  /* Look at the pretty-printer dictionary for each objfile
+     in the current program-space.  */
+  function = find_pretty_printer_from_objfiles (value);
+  if (function == NULL || function != Py_None)
+    return function;
+  Py_DECREF (function);
+
+  /* Look at the pretty-printer dictionary for the current program-space.  */
+  function = find_pretty_printer_from_progspace (value);
+  if (function == NULL || function != Py_None)
+    return function;
+  Py_DECREF (function);
+
+  /* Look at the pretty-printer dictionary in the gdb module.  */
+  function = find_pretty_printer_from_gdb (value);
+  return function;
+}
 
 /* Pretty-print a single value, via the printer object PRINTER.
    If the function returns a string, a PyObject containing the string
Index: python/py-progspace.c
===================================================================
RCS file: python/py-progspace.c
diff -N python/py-progspace.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ python/py-progspace.c	14 Apr 2010 22:34:36 -0000
@@ -0,0 +1,240 @@
+/* Python interface to program spaces.
+
+   Copyright (C) 2010 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include "defs.h"
+#include "python-internal.h"
+#include "charset.h"
+#include "progspace.h"
+#include "objfiles.h"
+#include "language.h"
+
+typedef struct
+{
+  PyObject_HEAD
+
+  /* The corresponding pspace.  */
+  struct program_space *pspace;
+
+  /* The pretty-printer list of functions.  */
+  PyObject *printers;
+} pspace_object;
+
+static PyTypeObject pspace_object_type;
+
+static const struct program_space_data *pspy_pspace_data_key;
+
+\f
+
+/* An Objfile method which returns the objfile's file name, or None.  */
+
+static PyObject *
+pspy_get_filename (PyObject *self, void *closure)
+{
+  pspace_object *obj = (pspace_object *) self;
+  if (obj->pspace)
+    {
+      struct objfile *objfile = obj->pspace->symfile_object_file;
+      if (objfile && objfile->name)
+	return PyString_Decode (objfile->name, strlen (objfile->name),
+				host_charset (), NULL);
+    }
+  Py_RETURN_NONE;
+}
+
+static void
+pspy_dealloc (PyObject *self)
+{
+  pspace_object *ps_self = (pspace_object *) self;
+  Py_XDECREF (ps_self->printers);
+  self->ob_type->tp_free (self);
+}
+
+static PyObject *
+pspy_new (PyTypeObject *type, PyObject *args, PyObject *keywords)
+{
+  pspace_object *self = (pspace_object *) type->tp_alloc (type, 0);
+  if (self)
+    {
+      self->pspace = NULL;
+
+      self->printers = PyList_New (0);
+      if (!self->printers)
+	{
+	  Py_DECREF (self);
+	  return NULL;
+	}
+    }
+  return (PyObject *) self;
+}
+
+PyObject *
+pspy_get_printers (PyObject *o, void *ignore)
+{
+  pspace_object *self = (pspace_object *) o;
+  Py_INCREF (self->printers);
+  return self->printers;
+}
+
+static int
+pspy_set_printers (PyObject *o, PyObject *value, void *ignore)
+{
+  PyObject *tmp;
+  pspace_object *self = (pspace_object *) o;
+  if (! value)
+    {
+      PyErr_SetString (PyExc_TypeError,
+		       "cannot delete the pretty_printers attribute");
+      return -1;
+    }
+
+  if (! PyList_Check (value))
+    {
+      PyErr_SetString (PyExc_TypeError,
+		       "the pretty_printers attribute must be a list");
+      return -1;
+    }
+
+  /* Take care in case the LHS and RHS are related somehow.  */
+  tmp = self->printers;
+  Py_INCREF (value);
+  self->printers = value;
+  Py_XDECREF (tmp);
+
+  return 0;
+}
+
+\f
+
+/* Clear the PSPACE pointer in a Pspace object and remove the reference.  */
+
+static void
+py_free_pspace (struct program_space *pspace, void *datum)
+{
+  struct cleanup *cleanup;
+  pspace_object *object = datum;
+  /* FIXME: What's the right way to get a program space's arch?
+     There may be multiple.  */
+  struct gdbarch *arch = get_objfile_arch (pspace->symfile_object_file);
+
+  cleanup = ensure_python_env (arch, current_language);
+  object->pspace = NULL;
+  Py_DECREF ((PyObject *) object);
+  do_cleanups (cleanup);
+}
+
+/* Return a borrowed reference to the Python object of type Pspace
+   representing PSPACE.  If the object has already been created,
+   return it.  Otherwise, create it.  Return NULL and set the Python
+   error on failure.  */
+
+PyObject *
+pspace_to_pspace_object (struct program_space *pspace)
+{
+  pspace_object *object;
+
+  object = program_space_data (pspace, pspy_pspace_data_key);
+  if (!object)
+    {
+      object = PyObject_New (pspace_object, &pspace_object_type);
+      if (object)
+	{
+	  PyObject *dict;
+
+	  object->pspace = pspace;
+
+	  object->printers = PyList_New (0);
+	  if (!object->printers)
+	    {
+	      Py_DECREF (object);
+	      return NULL;
+	    }
+
+	  set_program_space_data (pspace, pspy_pspace_data_key, object);
+	}
+    }
+
+  return (PyObject *) object;
+}
+
+void
+gdbpy_initialize_pspace (void)
+{
+  pspy_pspace_data_key
+    = register_program_space_data_with_cleanup (py_free_pspace);
+
+  if (PyType_Ready (&pspace_object_type) < 0)
+    return;
+
+  Py_INCREF (&pspace_object_type);
+  PyModule_AddObject (gdb_module, "Progspace", (PyObject *) &pspace_object_type);
+}
+
+\f
+
+static PyGetSetDef pspace_getset[] =
+{
+  { "filename", pspy_get_filename, NULL,
+    "The progspace's main filename, or None.", NULL },
+  { "pretty_printers", pspy_get_printers, pspy_set_printers,
+    "Pretty printers.", NULL },
+  { NULL }
+};
+
+static PyTypeObject pspace_object_type =
+{
+  PyObject_HEAD_INIT (NULL)
+  0,				  /*ob_size*/
+  "gdb.Progspace",		  /*tp_name*/
+  sizeof (pspace_object),	  /*tp_basicsize*/
+  0,				  /*tp_itemsize*/
+  pspy_dealloc,			  /*tp_dealloc*/
+  0,				  /*tp_print*/
+  0,				  /*tp_getattr*/
+  0,				  /*tp_setattr*/
+  0,				  /*tp_compare*/
+  0,				  /*tp_repr*/
+  0,				  /*tp_as_number*/
+  0,				  /*tp_as_sequence*/
+  0,				  /*tp_as_mapping*/
+  0,				  /*tp_hash */
+  0,				  /*tp_call*/
+  0,				  /*tp_str*/
+  0,				  /*tp_getattro*/
+  0,				  /*tp_setattro*/
+  0,				  /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT,		  /*tp_flags*/
+  "GDB progspace object",	  /* tp_doc */
+  0,				  /* tp_traverse */
+  0,				  /* tp_clear */
+  0,				  /* tp_richcompare */
+  0,				  /* tp_weaklistoffset */
+  0,				  /* tp_iter */
+  0,				  /* tp_iternext */
+  0,				  /* tp_methods */
+  0,				  /* tp_members */
+  pspace_getset,		  /* tp_getset */
+  0,				  /* tp_base */
+  0,				  /* tp_dict */
+  0,				  /* tp_descr_get */
+  0,				  /* tp_descr_set */
+  0,				  /* tp_dictoffset */
+  0,				  /* tp_init */
+  0,				  /* tp_alloc */
+  pspy_new,			  /* tp_new */
+};
Index: python/python-internal.h
===================================================================
RCS file: /cvs/src/src/gdb/python/python-internal.h,v
retrieving revision 1.23
diff -u -p -r1.23 python-internal.h
--- python/python-internal.h	9 Apr 2010 09:41:43 -0000	1.23
+++ python/python-internal.h	14 Apr 2010 22:34:36 -0000
@@ -68,6 +68,7 @@ typedef int Py_ssize_t;
 struct block;
 struct value;
 struct language_defn;
+struct program_space;
 
 extern PyObject *gdb_module;
 extern PyTypeObject value_object_type;
@@ -91,8 +92,11 @@ PyObject *symbol_to_symbol_object (struc
 PyObject *block_to_block_object (struct block *block, struct objfile *objfile);
 PyObject *value_to_value_object (struct value *v);
 PyObject *type_to_type_object (struct type *);
-PyObject *objfile_to_objfile_object (struct objfile *);
 
+PyObject *pspace_to_pspace_object (struct program_space *);
+PyObject *pspy_get_printers (PyObject *, void *);
+
+PyObject *objfile_to_objfile_object (struct objfile *);
 PyObject *objfpy_get_printers (PyObject *, void *);
 
 struct block *block_object_to_block (PyObject *obj);
@@ -112,6 +116,7 @@ void gdbpy_initialize_symtabs (void);
 void gdbpy_initialize_blocks (void);
 void gdbpy_initialize_types (void);
 void gdbpy_initialize_functions (void);
+void gdbpy_initialize_pspace (void);
 void gdbpy_initialize_objfile (void);
 void gdbpy_initialize_breakpoints (void);
 void gdbpy_initialize_lazy_string (void);
Index: python/python.c
===================================================================
RCS file: /cvs/src/src/gdb/python/python.c,v
retrieving revision 1.30
diff -u -p -r1.30 python.c
--- python/python.c	14 Apr 2010 13:18:55 -0000	1.30
+++ python/python.c	14 Apr 2010 22:34:36 -0000
@@ -23,6 +23,7 @@
 #include "ui-out.h"
 #include "cli/cli-script.h"
 #include "gdbcmd.h"
+#include "progspace.h"
 #include "objfiles.h"
 #include "observer.h"
 #include "value.h"
@@ -417,6 +418,47 @@ gdbpy_print_stack (void)
 
 \f
 
+/* Return the current Progspace.
+   There always is one.  */
+
+static PyObject *
+gdbpy_get_current_progspace (PyObject *unused1, PyObject *unused2)
+{
+  PyObject *result;
+
+  result = pspace_to_pspace_object (current_program_space);
+  if (result)
+    Py_INCREF (result);
+  return result;
+}
+
+/* Return a sequence holding all the Progspaces.  */
+
+static PyObject *
+gdbpy_progspaces (PyObject *unused1, PyObject *unused2)
+{
+  struct program_space *ps;
+  PyObject *list;
+
+  list = PyList_New (0);
+  if (!list)
+    return NULL;
+
+  ALL_PSPACES (ps)
+  {
+    PyObject *item = pspace_to_pspace_object (ps);
+    if (!item || PyList_Append (list, item) == -1)
+      {
+	Py_DECREF (list);
+	return NULL;
+      }
+  }
+
+  return list;
+}
+
+\f
+
 /* The "current" objfile.  This is set when gdb detects that a new
    objfile has been loaded.  It is only set for the duration of a call
    to gdbpy_new_objfile; it is NULL at other times.  */
@@ -512,6 +554,7 @@ gdbpy_get_current_objfile (PyObject *unu
 }
 
 /* Return a sequence holding all the Objfiles.  */
+
 static PyObject *
 gdbpy_objfiles (PyObject *unused1, PyObject *unused2)
 {
@@ -669,6 +718,7 @@ Enables or disables auto-loading of Pyth
   gdbpy_initialize_blocks ();
   gdbpy_initialize_functions ();
   gdbpy_initialize_types ();
+  gdbpy_initialize_pspace ();
   gdbpy_initialize_objfile ();
   gdbpy_initialize_breakpoints ();
   gdbpy_initialize_lazy_string ();
@@ -735,6 +785,11 @@ static PyMethodDef GdbMethods[] =
   { "default_visualizer", gdbpy_default_visualizer, METH_VARARGS,
     "Find the default visualizer for a Value." },
 
+  { "current_progspace", gdbpy_get_current_progspace, METH_NOARGS,
+    "Return the current Progspace." },
+  { "progspaces", gdbpy_progspaces, METH_NOARGS,
+    "Return a sequence of all progspaces." },
+
   { "current_objfile", gdbpy_get_current_objfile, METH_NOARGS,
     "Return the current Objfile being loaded, or None." },
   { "objfiles", gdbpy_objfiles, METH_NOARGS,
Index: testsuite/gdb.python/py-progspace.c
===================================================================
RCS file: testsuite/gdb.python/py-progspace.c
diff -N testsuite/gdb.python/py-progspace.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.python/py-progspace.c	14 Apr 2010 22:34:36 -0000
@@ -0,0 +1,22 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2010 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+int
+main ()
+{
+  return 0;
+}
Index: testsuite/gdb.python/py-progspace.exp
===================================================================
RCS file: testsuite/gdb.python/py-progspace.exp
diff -N testsuite/gdb.python/py-progspace.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.python/py-progspace.exp	14 Apr 2010 22:34:36 -0000
@@ -0,0 +1,47 @@
+# Copyright (C) 2010 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# This file is part of the GDB testsuite.  It tests the program space
+# support in Python.
+
+if $tracelevel then {
+    strace $tracelevel
+}
+
+set testfile "py-progspace"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+    untested "Couldn't compile ${srcfile}"
+    return -1
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+# Skip all tests if Python scripting is not enabled.
+if { [skip_python_tests] } { continue }
+
+gdb_test "python print gdb.current_progspace().filename" "None" \
+  "current progspace filename (None)"
+gdb_test "python print gdb.progspaces()" "\\\[<gdb.Progspace object at $hex>\\\]"
+
+gdb_load ${binfile}
+
+gdb_test "python print gdb.current_progspace().filename" "py-progspace" \
+  "current progspace filename (py-progspace)"

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

end of thread, other threads:[~2010-04-14 22:47 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-04-07 17:32 [RFA][python] Add program space support Doug Evans
2010-04-07 17:39 ` Doug Evans
2010-04-07 17:54   ` Eli Zaretskii
2010-04-07 17:52 ` Eli Zaretskii
2010-04-08 22:24   ` Doug Evans
2010-04-09  7:37     ` Eli Zaretskii
2010-04-09 15:34       ` Doug Evans
2010-04-09 15:42         ` Pedro Alves
2010-04-14 22:47           ` Doug Evans

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox