[doc,RFA] Add ability to set random attributes in python objfiles,progspaces
Commit Message
Phil Muldoon writes:
> On 10/10/14 18:35, Doug Evans wrote:
> > Phil Muldoon writes:
> > > Maybe add a small example here as you did with gdb.Objfile? Or maybe
> > > an xref. One of my goals in the next year is to add (and backfill in
> > > existing documentation) more example led documentation for Python.
> > > Sometimes an example speaks (ten) thousand words!
> >
> > I couldn't think of a simple one.
>
> Maybe document (as in describe) a more complex one?
How about this?
2014-10-17 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.
doc/
* 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.
testsuite/
* 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.
Comments
> From: Doug Evans <dje@google.com>
> Date: Fri, 17 Oct 2014 13:28:54 -0700
> Cc: gdb-patches@sourceware.org
>
> Phil Muldoon writes:
> > On 10/10/14 18:35, Doug Evans wrote:
> > > Phil Muldoon writes:
> > > > Maybe add a small example here as you did with gdb.Objfile? Or maybe
> > > > an xref. One of my goals in the next year is to add (and backfill in
> > > > existing documentation) more example led documentation for Python.
> > > > Sometimes an example speaks (ten) thousand words!
> > >
> > > I couldn't think of a simple one.
> >
> > Maybe document (as in describe) a more complex one?
>
> How about this?
Fine with me, thanks.
On Fri, Oct 17, 2014 at 10:39 PM, Eli Zaretskii <eliz@gnu.org> wrote:
>> From: Doug Evans <dje@google.com>
>> Date: Fri, 17 Oct 2014 13:28:54 -0700
>> Cc: gdb-patches@sourceware.org
>>
>> Phil Muldoon writes:
>> > On 10/10/14 18:35, Doug Evans wrote:
>> > > Phil Muldoon writes:
>> > > > Maybe add a small example here as you did with gdb.Objfile? Or maybe
>> > > > an xref. One of my goals in the next year is to add (and backfill in
>> > > > existing documentation) more example led documentation for Python.
>> > > > Sometimes an example speaks (ten) thousand words!
>> > >
>> > > I couldn't think of a simple one.
>> >
>> > Maybe document (as in describe) a more complex one?
>>
>> How about this?
>
> Fine with me, thanks.
Thanks. Phil?
On 21/10/14 17:53, Doug Evans wrote:
> On Fri, Oct 17, 2014 at 10:39 PM, Eli Zaretskii <eliz@gnu.org> wrote:
>>> From: Doug Evans <dje@google.com>
>>> Date: Fri, 17 Oct 2014 13:28:54 -0700
>>> Cc: gdb-patches@sourceware.org
>>>
>>> Phil Muldoon writes:
>>> > On 10/10/14 18:35, Doug Evans wrote:
>>> > > Phil Muldoon writes:
>>> > > > Maybe add a small example here as you did with gdb.Objfile? Or maybe
>>> > > > an xref. One of my goals in the next year is to add (and backfill in
>>> > > > existing documentation) more example led documentation for Python.
>>> > > > Sometimes an example speaks (ten) thousand words!
>>> > >
>>> > > I couldn't think of a simple one.
>>> >
>>> > Maybe document (as in describe) a more complex one?
>>>
>>> How about this?
>> Fine with me, thanks.
> Thanks. Phil?
Apologies for the delay. Looks super.
Thanks Doug.
Cheers,
Phil
On Tue, Oct 21, 2014 at 11:23 AM, Phil Muldoon <pmuldoon@redhat.com> wrote:
> On 21/10/14 17:53, Doug Evans wrote:
>> On Fri, Oct 17, 2014 at 10:39 PM, Eli Zaretskii <eliz@gnu.org> wrote:
>>>> From: Doug Evans <dje@google.com>
>>>> Date: Fri, 17 Oct 2014 13:28:54 -0700
>>>> Cc: gdb-patches@sourceware.org
>>>>
>>>> Phil Muldoon writes:
>>>> > On 10/10/14 18:35, Doug Evans wrote:
>>>> > > Phil Muldoon writes:
>>>> > > > Maybe add a small example here as you did with gdb.Objfile? Or maybe
>>>> > > > an xref. One of my goals in the next year is to add (and backfill in
>>>> > > > existing documentation) more example led documentation for Python.
>>>> > > > Sometimes an example speaks (ten) thousand words!
>>>> > >
>>>> > > I couldn't think of a simple one.
>>>> >
>>>> > Maybe document (as in describe) a more complex one?
>>>>
>>>> How about this?
>>> Fine with me, thanks.
>> Thanks. Phil?
>
> Apologies for the delay. Looks super.
No worries on the delay. :-)
Committed, thanks.
@@ -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:
@@ -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 ()
@@ -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 */
@@ -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 */
@@ -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"
@@ -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"