From patchwork Fri Oct 17 20:28:54 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Doug Evans X-Patchwork-Id: 3275 Received: (qmail 3322 invoked by alias); 17 Oct 2014 20:29:01 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 3307 invoked by uid 89); 17 Oct 2014 20:29:00 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.8 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_LOW, RP_MATCHES_RCVD, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-ie0-f201.google.com Received: from mail-ie0-f201.google.com (HELO mail-ie0-f201.google.com) (209.85.223.201) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Fri, 17 Oct 2014 20:28:59 +0000 Received: by mail-ie0-f201.google.com with SMTP id rl12so211401iec.2 for ; Fri, 17 Oct 2014 13:28:56 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:mime-version:content-type :content-transfer-encoding:message-id:date:to:cc:subject:in-reply-to :references; bh=+SjIsBkXXPQwowmiOmhUYd5d/3UyTEa5ULZ/1gLgzHc=; b=kyiMvJbnwLvXH5FlMbQe0tt2u9DBJuNP2DxPQSr/17sMm4iRECTMQhvI9NhMbmTnuD cNGun1vqwJN+h+7HYnQQ4EcL5uH1dj17Ql+Ib92LKcBpux5p946rz1zdGiHyqrsLXIFh zAZqci9fxTk3crdGB8gQbcrqTZBYViQFnnlMp1bRAE2piiKAWf7PEjp4VW0/ooq9kxMB u7lIw3oyL45MAsotBzG+ljd8qamNRSWFdFGtcyj0y51NE82YNe/4kbgBhT3NMMlOvGZk 6Qj5vrWRJIp+0Ku5+cjXQixEiAX+v7Xi19Fr7uKrXptnSolITsG7EFCVslPtivzld/wD B8xg== X-Gm-Message-State: ALoCoQnyNqKhZkneBAtTdQ0xzY59KP7b4kBztFOGEh+1F+o2kzziAmLzjxb8Xin7dsoi2kkfcSg/cfEixB6fq5ibAWcoJi6AXa6bKhV4WH4qqPOeNo9NugvwNn+IsFJTI7BULPwtgRraq87x7qJslUbVN2w6HM3weUuH7+BelllI8oQC75nFoMo= X-Received: by 10.182.2.106 with SMTP id 10mr6978968obt.27.1413577735903; Fri, 17 Oct 2014 13:28:55 -0700 (PDT) Received: from corpmail-nozzle1-2.hot.corp.google.com ([100.108.1.103]) by gmr-mx.google.com with ESMTPS id l45si101978yha.2.2014.10.17.13.28.55 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 17 Oct 2014 13:28:55 -0700 (PDT) Received: from ruffy.mtv.corp.google.com ([172.17.128.44]) by corpmail-nozzle1-2.hot.corp.google.com with ESMTP id Xuf5X89z.1; Fri, 17 Oct 2014 13:28:55 -0700 From: Doug Evans MIME-Version: 1.0 Message-ID: <21569.31750.685018.824870@ruffy.mtv.corp.google.com> Date: Fri, 17 Oct 2014 13:28:54 -0700 To: Phil Muldoon , eliz@gnu.org Cc: gdb-patches@sourceware.org Subject: Re: [PATCH, doc RFA] Add ability to set random attributes in python objfiles, progspaces In-Reply-To: <5438247C.8050709@redhat.com> References: <54379223.3080305@redhat.com> <21560.6392.457864.907695@ruffy2.mtv.corp.google.com> <5438247C.8050709@redhat.com> X-IsSubscribed: yes 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 * 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. diff --git a/gdb/NEWS b/gdb/NEWS index 606fd16..33b2259 100644 --- 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: diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi index 43663d8..caaa259 100644 --- a/gdb/doc/python.texi +++ b/gdb/doc/python.texi @@ -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 () diff --git a/gdb/python/py-objfile.c b/gdb/python/py-objfile.c index e868223..c99de87 100644 --- a/gdb/python/py-objfile.c +++ b/gdb/python/py-objfile.c @@ -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 */ diff --git a/gdb/python/py-progspace.c b/gdb/python/py-progspace.c index 4280032..96339b1 100644 --- a/gdb/python/py-progspace.c +++ b/gdb/python/py-progspace.c @@ -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 */ diff --git a/gdb/testsuite/gdb.python/py-objfile.exp b/gdb/testsuite/gdb.python/py-objfile.exp index 8796170..7bf41ed 100644 --- a/gdb/testsuite/gdb.python/py-objfile.exp +++ b/gdb/testsuite/gdb.python/py-objfile.exp @@ -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" diff --git a/gdb/testsuite/gdb.python/py-progspace.exp b/gdb/testsuite/gdb.python/py-progspace.exp index 2fcfdb9..a47fae6 100644 --- a/gdb/testsuite/gdb.python/py-progspace.exp +++ b/gdb/testsuite/gdb.python/py-progspace.exp @@ -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_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"