This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFA] add support for disabling individual pretty-printers


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.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]