Add ability to add attributes to gdb.Objfile and gdb.Progspace objects.
authorDoug Evans <dje@google.com>
Fri, 31 Oct 2014 00:05:17 +0000 (17:05 -0700)
committerDoug Evans <dje@google.com>
Fri, 31 Oct 2014 00:05:17 +0000 (17:05 -0700)
gdb/ChangeLog:

* NEWS: Mention ability add attributes to gdb.Objfile and
gdb.Progspace objects.
* python/py-objfile.c (objfile_object): New member dict.
(objfpy_dealloc): Py_XDECREF dict.
(objfpy_initialize): Initialize dict.
(objfile_getset): Add __dict__.
(objfile_object_type): Set tp_dictoffset member.
* python/py-progspace.c (progspace_object): New member dict.
(pspy_dealloc): Py_XDECREF dict.
(pspy_initialize): Initialize dict.
(pspace_getset): Add __dict__.
(pspace_object_type): Set tp_dictoffset member.

gdb/doc/ChangeLog:

* python.texi (Progspaces In Python): Document ability to add
random attributes to gdb.Progspace objects.
(Objfiles In Python): Document ability to add random attributes to
gdb.objfile objects.

gdb/testsuite/ChangeLog:

* gdb.python/py-objfile.exp: Add tests for setting random attributes
in objfiles.
* gdb.python/py-progspace.exp: Add tests for setting random attributes
in progspaces.

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

index 6d4a9af708d668c9b92fe507494db43487ece803..543dcb342c9536025f7c98a7119b3dfebaf0425d 100644 (file)
@@ -1,3 +1,18 @@
+2014-10-30  Doug Evans  <dje@google.com>
+
+       * NEWS: Mention ability add attributes to gdb.Objfile and
+       gdb.Progspace objects.
+       * python/py-objfile.c (objfile_object): New member dict.
+       (objfpy_dealloc): Py_XDECREF dict.
+       (objfpy_initialize): Initialize dict.
+       (objfile_getset): Add __dict__.
+       (objfile_object_type): Set tp_dictoffset member.
+       * python/py-progspace.c (progspace_object): New member dict.
+       (pspy_dealloc): Py_XDECREF dict.
+       (pspy_initialize): Initialize dict.
+       (pspace_getset): Add __dict__.
+       (pspace_object_type): Set tp_dictoffset member.
+
 2014-10-30  Yao Qi  <yao@codesourcery.com>
 
        * python/lib/gdb/command/prompt.py (before_prompt_hook): Don't
index 01cdc365a30e1f6b7310a44bc08ea83e46341895..649c29ee8eb387f204f41102f47a915f14c96975 100644 (file)
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -13,6 +13,7 @@
      which is the gdb.Progspace object of the containing program space.
   ** A new event "gdb.clear_objfiles" has been added, triggered when
      selecting a new file to debug.
+  ** You can now add attributes to gdb.Objfile and gdb.Progspace objects.
 
 * New Python-based convenience functions:
 
index f60fd8fc0b24715f137c2f448ee1b71e2f613a01..2e619da5dad321ab910bdb7219875e647053ebc2 100644 (file)
@@ -1,3 +1,10 @@
+2014-10-30  Doug Evans  <dje@google.com>
+
+       * python.texi (Progspaces In Python): Document ability to add
+       random attributes to gdb.Progspace objects.
+       (Objfiles In Python): Document ability to add random attributes to
+       gdb.objfile objects.
+
 2014-10-27  Pedro Alves  <palves@redhat.com>
 
        * gdb.texinfo (Continuing and Stepping): Add cross reference to
index f1fd841bf9c2d19b42cccad351751d3cf44cd2de..5b35306135eedc7d99c537826d3b6653df0185c3 100644 (file)
@@ -3366,6 +3366,50 @@ The @code{frame_filters} attribute is a dictionary of frame filter
 objects.  @xref{Frame Filter API}, for more information.
 @end defvar
 
+One may add arbitrary attributes to @code{gdb.Progspace} objects
+in the usual Python way.
+This is useful if, for example, one needs to do some extra record keeping
+associated with the program space.
+
+In this contrived example, we want to perform some processing when
+an objfile with a certain symbol is loaded, but we only want to do
+this once because it is expensive.  To achieve this we record the results
+with the program space because we can't predict when the desired objfile
+will be loaded.
+
+@smallexample
+(gdb) python
+def clear_objfiles_handler(event):
+    event.progspace.expensive_computation = None
+def expensive(symbol):
+    """A mock routine to perform an "expensive" computation on symbol."""
+    print "Computing the answer to the ultimate question ..."
+    return 42
+def new_objfile_handler(event):
+    objfile = event.new_objfile
+    progspace = objfile.progspace
+    if not hasattr(progspace, 'expensive_computation') or \
+            progspace.expensive_computation is None:
+        # We use 'main' for the symbol to keep the example simple.
+        # Note: There's no current way to constrain the lookup
+        # to one objfile.
+        symbol = gdb.lookup_global_symbol('main')
+        if symbol is not None:
+            progspace.expensive_computation = expensive(symbol)
+gdb.events.clear_objfiles.connect(clear_objfiles_handler)
+gdb.events.new_objfile.connect(new_objfile_handler)
+end
+(gdb) file /tmp/hello
+Reading symbols from /tmp/hello...done.
+Computing the answer to the ultimate question ...
+(gdb) python print gdb.current_progspace().expensive_computation
+42
+(gdb) run
+Starting program: /tmp/hello
+Hello.
+[Inferior 1 (process 4242) exited normally]
+@end smallexample
+
 @node Objfiles In Python
 @subsubsection Objfiles In Python
 
@@ -3426,6 +3470,28 @@ The @code{frame_filters} attribute is a dictionary of frame filter
 objects.  @xref{Frame Filter API}, for more information.
 @end defvar
 
+One may add arbitrary attributes to @code{gdb.Objfile} objects
+in the usual Python way.
+This is useful if, for example, one needs to do some extra record keeping
+associated with the objfile.
+
+In this contrived example we record the time when @value{GDBN}
+loaded the objfile.
+
+@smallexample
+(gdb) python
+import datetime
+def new_objfile_handler(event):
+    # Set the time_loaded attribute of the new objfile.
+    event.new_objfile.time_loaded = datetime.datetime.today()
+gdb.events.new_objfile.connect(new_objfile_handler)
+end
+(gdb) file ./hello
+Reading symbols from ./hello...done.
+(gdb) python print gdb.objfiles()[0].time_loaded
+2014-10-09 11:41:36.770345
+@end smallexample
+
 A @code{gdb.Objfile} object has the following methods:
 
 @defun Objfile.is_valid ()
index e8682230882d10d33e5188b82c93dc1ceea9d4c0..c99de87e33d45ca45fe86ddd7b24e5e309e91faf 100644 (file)
@@ -30,6 +30,10 @@ typedef struct
   /* The corresponding objfile.  */
   struct objfile *objfile;
 
+  /* Dictionary holding user-added attributes.
+     This is the __dict__ attribute of the object.  */
+  PyObject *dict;
+
   /* The pretty-printer list of functions.  */
   PyObject *printers;
 
@@ -85,6 +89,7 @@ objfpy_dealloc (PyObject *o)
 {
   objfile_object *self = (objfile_object *) o;
 
+  Py_XDECREF (self->dict);
   Py_XDECREF (self->printers);
   Py_XDECREF (self->frame_filters);
   Py_XDECREF (self->type_printers);
@@ -99,6 +104,7 @@ static int
 objfpy_initialize (objfile_object *self)
 {
   self->objfile = NULL;
+  self->dict = NULL;
 
   self->printers = PyList_New (0);
   if (self->printers == NULL)
@@ -354,6 +360,8 @@ Return true if this object file is valid, false if not." },
 
 static PyGetSetDef objfile_getset[] =
 {
+  { "__dict__", gdb_py_generic_dict, NULL,
+    "The __dict__ for this objfile.", &objfile_object_type },
   { "filename", objfpy_get_filename, NULL,
     "The objfile's filename, or None.", NULL },
   { "progspace", objfpy_get_progspace, NULL,
@@ -405,7 +413,7 @@ static PyTypeObject objfile_object_type =
   0,                             /* tp_dict */
   0,                             /* tp_descr_get */
   0,                             /* tp_descr_set */
-  0,                             /* tp_dictoffset */
+  offsetof (objfile_object, dict), /* tp_dictoffset */
   0,                             /* tp_init */
   0,                             /* tp_alloc */
   objfpy_new,                    /* tp_new */
index 4280032744d4e892963d998db6f773de42ab27ee..96339b140d59e1347be33d77cfe9c53bb8310d14 100644 (file)
@@ -32,6 +32,10 @@ typedef struct
   /* The corresponding pspace.  */
   struct program_space *pspace;
 
+  /* Dictionary holding user-added attributes.
+     This is the __dict__ attribute of the object.  */
+  PyObject *dict;
+
   /* The pretty-printer list of functions.  */
   PyObject *printers;
 
@@ -75,6 +79,7 @@ pspy_dealloc (PyObject *self)
 {
   pspace_object *ps_self = (pspace_object *) self;
 
+  Py_XDECREF (ps_self->dict);
   Py_XDECREF (ps_self->printers);
   Py_XDECREF (ps_self->frame_filters);
   Py_XDECREF (ps_self->type_printers);
@@ -89,6 +94,7 @@ static int
 pspy_initialize (pspace_object *self)
 {
   self->pspace = NULL;
+  self->dict = NULL;
 
   self->printers = PyList_New (0);
   if (self->printers == NULL)
@@ -331,6 +337,8 @@ gdbpy_initialize_pspace (void)
 
 static PyGetSetDef pspace_getset[] =
 {
+  { "__dict__", gdb_py_generic_dict, NULL,
+    "The __dict__ for this progspace.", &pspace_object_type },
   { "filename", pspy_get_filename, NULL,
     "The progspace's main filename, or None.", NULL },
   { "pretty_printers", pspy_get_printers, pspy_set_printers,
@@ -380,7 +388,7 @@ static PyTypeObject pspace_object_type =
   0,                             /* tp_dict */
   0,                             /* tp_descr_get */
   0,                             /* tp_descr_set */
-  0,                             /* tp_dictoffset */
+  offsetof (pspace_object, dict), /* tp_dictoffset */
   0,                             /* tp_init */
   0,                             /* tp_alloc */
   pspy_new,                      /* tp_new */
index 0139f4c0b1019105a549bf6db546ac0e53741db5..4f2f208230a9f609786ca3551b210e76fa42d0e7 100644 (file)
@@ -1,3 +1,10 @@
+2014-10-30  Doug Evans  <dje@google.com>
+
+       * gdb.python/py-objfile.exp: Add tests for setting random attributes
+       in objfiles.
+       * gdb.python/py-progspace.exp: Add tests for setting random attributes
+       in progspaces.
+
 2014-10-30  Janis Johnson  <janisjo@codesourcery.com>
 
        * gdb.base/fullpath-expand.exp: Skip for a remote host.
index 87961703f0923b81c1fa8ab1305a0a60908cd4b1..7bf41ed9d07f95e4ab06a4b445fe2b1c1fbd34ad 100644 (file)
@@ -46,3 +46,8 @@ gdb_test "python print (objfile.is_valid())" "True" \
 gdb_unload
 gdb_test "python print (objfile.is_valid())" "False" \
   "Get objfile validity after unload"
+
+gdb_py_test_silent_cmd "python objfile.random_attribute = 42" \
+    "Set random attribute in objfile" 1
+gdb_test "python print (objfile.random_attribute)" "42" \
+    "Verify set of random attribute in objfile"
index 2fcfdb9ed7c9037363b723e51638614010034991..a47fae657d556d9cfac781c3cd5dd61481afa1df 100644 (file)
@@ -16,6 +16,8 @@
 # This file is part of the GDB testsuite.  It tests the program space
 # support in Python.
 
+load_lib gdb-python.exp
+
 standard_testfile
 
 if {[build_executable $testfile.exp $testfile $srcfile debug] == -1} {
@@ -37,5 +39,13 @@ gdb_test "python print (gdb.progspaces())" "\\\[<gdb.Progspace object at $hex>\\
 
 gdb_load ${binfile}
 
-gdb_test "python print (gdb.current_progspace().filename)" "py-progspace" \
+gdb_py_test_silent_cmd "python progspace = gdb.current_progspace()" \
+    "Get current progspace" 1
+
+gdb_test "python print (progspace.filename)" "py-progspace" \
   "current progspace filename (py-progspace)"
+
+gdb_py_test_silent_cmd "python progspace.random_attribute = 42" \
+    "Set random attribute in progspace" 1
+gdb_test "python print (progspace.random_attribute)" "42" \
+    "Verify set of random attribute in progspace"