Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: dje@google.com (Doug Evans)
To: gdb-patches@sourceware.org
Subject: [RFA] add support for disabling individual pretty-printers
Date: Thu, 20 May 2010 07:34:00 -0000	[thread overview]
Message-ID: <20100520071212.E4A8484398@ruffy.mtv.corp.google.com> (raw)

Hi.

As discussed in irc, I'd like to add support for disabling
individual pretty-printers.  Broken printers do get installed
and/or the underlying data structures do change with developers
not always updating the pretty-printer.  When this happens
the consequences to a user's debugging session can be severe enough
that IMO we need to do *something*.
The user may be in a completely different group and/or not have
any knowledge of pretty-printer details.  Asking him/her to put up
with the breakage until the printer is fixed is unreasonable (IMO).

The approach below uses the presence of an "enabled" attribute
on the lookup function (or callable object!) to control the
enabling/disabling.

Ok to check in?

For reference sake, I'd also like to establish some conventions
when writing pretty printers but that's for another patch.
E.g., some pretty printers handle *lots* of types (e.g. libstdc++'s
pretty printer).
It'd be unfortunate to have to disable pretty-printing of all
of the handled types just because one of them is broken.

2010-05-19  Doug Evans  <dje@google.com>

	Add support for enabling/disabling individual pretty-printers.	
	* py-prettyprint.c (search_pp_list): Skip disabled printers.
	* python-internal.h (gdbpy_enabled_cst): Declare.
	* python.c (gdbpy_enabled_cst): Define.
	(_initialize_python): Initialize gdbpy_enabled_cst.
	* NEWS: Add entry.

	doc/
	* gdb.texinfo (Python API): New node `Disabling Pretty-Printers'.

	testsuite/
	* gdb.python/py-prettyprint.exp: Add new test for enabled and
	disabled printers.
	* gdb.python/py-prettyprint.py (disable_lookup_function): New function.
	(enable_lookup_function): New function.

Index: doc/gdb.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
retrieving revision 1.716
diff -u -p -r1.716 gdb.texinfo
--- doc/gdb.texinfo	29 Apr 2010 15:45:56 -0000	1.716
+++ doc/gdb.texinfo	20 May 2010 06:50:57 -0000
@@ -19940,6 +19940,7 @@ situation, a Python @code{KeyboardInterr
 * Types In Python::             Python representation of types.
 * Pretty Printing API::         Pretty-printing values.
 * Selecting Pretty-Printers::   How GDB chooses a pretty-printer.
+* Disabling Pretty-Printers::   Disabling broken printers.
 * Commands In Python::          Implementing new commands in Python.
 * Parameters In Python::        Adding new @value{GDBN} parameters.
 * Functions In Python::         Writing new convenience functions.
@@ -20607,7 +20608,8 @@ If the result is not one of these types,
 @subsubsection Selecting Pretty-Printers
 
 The Python list @code{gdb.pretty_printers} contains an array of
-functions that have been registered via addition as a pretty-printer.
+functions or callable objects 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.
@@ -20620,13 +20622,14 @@ cannot create a pretty-printer for the v
 
 @value{GDBN} first checks the @code{pretty_printers} attribute of each
 @code{gdb.Objfile} in the current program space and iteratively calls
-each function in the list for that @code{gdb.Objfile} until it receives
+each enabled function (@pxref{Disabling Pretty-Printers})
+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.
+calling each enabled 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
+@code{gdb.pretty_printers} list, again calling each enabled function until an
 object is returned.
 
 The order in which the objfiles are searched is not specified.  For a
@@ -20711,6 +20714,24 @@ import gdb.libstdcxx.v6
 gdb.libstdcxx.v6.register_printers (gdb.current_objfile ())
 @end smallexample
 
+@node Disabling Pretty-Printers
+@subsubsection Disabling Pretty-Printers
+
+For various reasons a pretty-printer may not work.
+For example, the underlying data structure may have changed and
+the pretty-printer is out of date.
+
+The consequences of a broken pretty-printer are severe enough that
+@value{GDBN} provides support for enabling and disabling individual
+printers.  For example, if @code{print frame-arguments} is on,
+a backtrace can become highly illegible if any argument is printed
+with a broken printer.
+
+Pretty-printers are enabled and disabled by attaching an @code{enabled}
+attribute to the registered function or callable object.  If this attribute
+is present and its value is @code{False} the printer is disabled, otherwise
+the printer is enabled.
+
 @node Commands In Python
 @subsubsection Commands In Python
 
Index: python/py-prettyprint.c
===================================================================
RCS file: /cvs/src/src/gdb/python/py-prettyprint.c,v
retrieving revision 1.10
diff -u -p -r1.10 py-prettyprint.c
--- python/py-prettyprint.c	17 May 2010 21:23:25 -0000	1.10
+++ python/py-prettyprint.c	20 May 2010 06:50:57 -0000
@@ -48,6 +48,11 @@ search_pp_list (PyObject *list, PyObject
       if (! function)
 	return NULL;
 
+      /* Skip if disabled.  */
+      if (PyObject_HasAttr (function, gdbpy_enabled_cst)
+	  && ! PyObject_IsTrue (PyObject_GetAttr (function, gdbpy_enabled_cst)))
+	continue;
+
       printer = PyObject_CallFunctionObjArgs (function, value, NULL);
       if (! printer)
 	return NULL;
Index: python/python-internal.h
===================================================================
RCS file: /cvs/src/src/gdb/python/python-internal.h,v
retrieving revision 1.26
diff -u -p -r1.26 python-internal.h
--- python/python-internal.h	29 Apr 2010 15:45:56 -0000	1.26
+++ python/python-internal.h	20 May 2010 06:50:57 -0000
@@ -196,5 +196,6 @@ extern PyObject *gdbpy_doc_cst;
 extern PyObject *gdbpy_children_cst;
 extern PyObject *gdbpy_to_string_cst;
 extern PyObject *gdbpy_display_hint_cst;
+extern PyObject *gdbpy_enabled_cst;
 
 #endif /* GDB_PYTHON_INTERNAL_H */
Index: python/python.c
===================================================================
RCS file: /cvs/src/src/gdb/python/python.c,v
retrieving revision 1.38
diff -u -p -r1.38 python.c
--- python/python.c	19 May 2010 23:32:24 -0000	1.38
+++ python/python.c	20 May 2010 06:50:57 -0000
@@ -56,7 +56,7 @@ PyObject *gdbpy_to_string_cst;
 PyObject *gdbpy_children_cst;
 PyObject *gdbpy_display_hint_cst;
 PyObject *gdbpy_doc_cst;
-
+PyObject *gdbpy_enabled_cst;
 
 /* Architecture and language to be used in callbacks from
    the Python interpreter.  */
@@ -677,6 +683,7 @@ Enables or disables printing of Python s
   gdbpy_children_cst = PyString_FromString ("children");
   gdbpy_display_hint_cst = PyString_FromString ("display_hint");
   gdbpy_doc_cst = PyString_FromString ("__doc__");
+  gdbpy_enabled_cst = PyString_FromString ("enabled");
 
   /* Create a couple objects which are used for Python's stdout and
      stderr.  */
Index: testsuite/gdb.python/py-prettyprint.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.python/py-prettyprint.exp,v
retrieving revision 1.8
diff -u -p -r1.8 py-prettyprint.exp
--- testsuite/gdb.python/py-prettyprint.exp	14 Apr 2010 12:02:46 -0000	1.8
+++ testsuite/gdb.python/py-prettyprint.exp	20 May 2010 06:50:57 -0000
@@ -57,7 +57,6 @@ proc run_lang_tests {lang} {
     gdb_reinitialize_dir $srcdir/$subdir
     gdb_load ${binfile}
 
-
     if ![runto_main ] then {
 	perror "couldn't run to breakpoint"
 	return
@@ -109,3 +108,44 @@ proc run_lang_tests {lang} {
 
 run_lang_tests "c"
 run_lang_tests "c++"
+
+# Run various other tests.
+
+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
+gdb_load ${binfile}
+
+if ![runto_main ] then {
+    perror "couldn't run to breakpoint"
+    return
+}
+
+gdb_test "b [gdb_get_line_number {break to inspect} ${testfile}.c ]" \
+    ".*Breakpoint.*"
+gdb_test "continue" ".*Breakpoint.*"
+
+set remote_python_file [remote_download host ${srcdir}/${subdir}/${testfile}.py]
+
+gdb_test "python execfile ('${remote_python_file}')" ""
+
+gdb_test "print ss" " = a=< a=<1> b=<$hex>> b=< a=<2> b=<$hex>>" \
+    "print ss enabled #1"
+
+gdb_test "python disable_lookup_function ()" ""
+
+gdb_test "print ss" " = {a = {a = 1, b = $hex}, b = {a = 2, b = $hex}}" \
+    "print ss disabled"
+
+gdb_test "python enable_lookup_function ()" ""
+
+gdb_test "print ss" " = a=< a=<1> b=<$hex>> b=< a=<2> b=<$hex>>" \
+    "print ss enabled #2"
+
+remote_file host delete ${remote_python_file}
Index: testsuite/gdb.python/py-prettyprint.py
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.python/py-prettyprint.py,v
retrieving revision 1.6
diff -u -p -r1.6 py-prettyprint.py
--- testsuite/gdb.python/py-prettyprint.py	14 Apr 2010 12:02:46 -0000	1.6
+++ testsuite/gdb.python/py-prettyprint.py	20 May 2010 06:50:57 -0000
@@ -194,6 +194,11 @@ def lookup_function (val):
 
     return None
 
+def disable_lookup_function ():
+    lookup_function.enabled = False
+
+def enable_lookup_function ():
+    lookup_function.enabled = True
 
 def register_pretty_printers ():
     pretty_printers_dict[re.compile ('^struct s$')]   = pp_s
Index: NEWS
===================================================================
RCS file: /cvs/src/src/gdb/NEWS,v
retrieving revision 1.379
diff -u -p -r1.379 NEWS
--- NEWS	30 Apr 2010 07:04:52 -0000	1.379
+++ NEWS	20 May 2010 06:52:44 -0000
@@ -91,6 +91,8 @@ is now deprecated.
 
 ** Pretty-printers are now also looked up in the current program space.
 
+** Pretty-printers can now be individually enabled and disabled.
+
 ** GDB now looks for names of Python scripts to auto-load in a
    special section named `.debug_gdb_scripts', in addition to looking
    for a OBJFILE-gdb.py script when OBJFILE is read by the debugger.


             reply	other threads:[~2010-05-20  7:12 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-05-20  7:34 Doug Evans [this message]
2010-05-20 18:04 ` Eli Zaretskii
2010-05-20 19:57 ` Doug Evans
2010-06-02 22:41   ` Tom Tromey
2010-06-02 22:41 ` Tom Tromey

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20100520071212.E4A8484398@ruffy.mtv.corp.google.com \
    --to=dje@google.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox