Add support for enabling/disabling individual pretty-printers.
authorDoug Evans <dje@google.com>
Fri, 4 Jun 2010 18:18:28 +0000 (18:18 +0000)
committerDoug Evans <dje@google.com>
Fri, 4 Jun 2010 18:18:28 +0000 (18:18 +0000)
* python/py-prettyprint.c (search_pp_list): Skip disabled printers.
* python/python-internal.h (gdbpy_enabled_cst): Declare.
* python/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.

gdb/ChangeLog
gdb/NEWS
gdb/doc/ChangeLog
gdb/doc/gdb.texinfo
gdb/python/py-prettyprint.c
gdb/python/python-internal.h
gdb/python/python.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.python/py-prettyprint.exp
gdb/testsuite/gdb.python/py-prettyprint.py

index 86e49429cff67ca54ac78fc7dbfd05fc0ab42cf6..727a21d7360c584d77d4bd318ae6cacd95bcd3d5 100644 (file)
@@ -1,3 +1,12 @@
+2010-06-04  Doug Evans  <dje@google.com>
+
+       Add support for enabling/disabling individual pretty-printers.  
+       * python/py-prettyprint.c (search_pp_list): Skip disabled printers.
+       * python/python-internal.h (gdbpy_enabled_cst): Declare.
+       * python/python.c (gdbpy_enabled_cst): Define.
+       (_initialize_python): Initialize gdbpy_enabled_cst.
+       * NEWS: Add entry.
+
 2010-06-04  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
        * breakpoint.c (update_global_location_list): Fix comment typo.
index ad9a0f156a62d12f4dc5570407485ad15c030fbe..61208b12641923450586f68522780ac64d6581ac 100644 (file)
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -104,6 +104,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 dc082035fc17c62a95beb25d49cea4374062e59c..071a409ae368350553c4007b34d3e72e7cb83fa3 100644 (file)
@@ -1,3 +1,7 @@
+2010-06-04  Doug Evans  <dje@google.com>
+
+       * gdb.texinfo (Python API): New node `Disabling Pretty-Printers'.
+
 2010-06-03  Doug Evans  <dje@google.com>
 
        * gdbint.texinfo (Coding): Add subsection on command names.
index 37278c87ca4772cd6e2f4b9ed7f7abafad2ad4d5..fa7a0ec66bdb9abda9f67ba2c1cf083fa9caf7f6 100644 (file)
@@ -20019,6 +20019,7 @@ situation, a Python @code{KeyboardInterrupt} exception is thrown.
 * 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.
@@ -20710,7 +20711,8 @@ If the result is not one of these types, an exception is raised.
 @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.
@@ -20723,13 +20725,14 @@ cannot create a pretty-printer for the value, it should return
 
 @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
@@ -20814,6 +20817,25 @@ import gdb.libstdcxx.v6
 gdb.libstdcxx.v6.register_printers (gdb.current_objfile ())
 @end smallexample
 
+@node Disabling Pretty-Printers
+@subsubsection Disabling Pretty-Printers
+@cindex 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 e678898c00bb269b5609f53a1e4615adbc223771..4d60c96fc913d2eb5e852f1d8ccf16f85d65d55e 100644 (file)
@@ -48,6 +48,11 @@ search_pp_list (PyObject *list, PyObject *value)
       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 bc07b5d070b8b0bc09044d950292c5b77c591541..5bd2a4bb64ed830136a24deb5dda2de9eee659d4 100644 (file)
@@ -200,6 +200,7 @@ 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;
 
 extern PyObject *gdbpy_gdberror_exc;
 
index 0b7b7ba28ce71e3dbfaa41b5a9c7c8931255eba6..31880c107a5b65f8f7215976907a4f19a6b65cf9 100644 (file)
@@ -56,6 +56,7 @@ PyObject *gdbpy_to_string_cst;
 PyObject *gdbpy_children_cst;
 PyObject *gdbpy_display_hint_cst;
 PyObject *gdbpy_doc_cst;
+PyObject *gdbpy_enabled_cst;
 
 /* The GdbError exception.  */
 PyObject *gdbpy_gdberror_exc;
@@ -693,6 +694,7 @@ Enables or disables printing of Python stack traces."),
   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 45e4689bd41833cd5c226d99a67a225499b4901c..da283b86fc0c377bd3bf76fcb0ddc82a003c60c3 100644 (file)
@@ -1,3 +1,10 @@
+2010-06-04  Doug Evans  <dje@google.com>
+
+       * 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.
+
 2010-06-04  Tom Tromey  <tromey@redhat.com>
 
        * gdb.python/py-value.exp (test_value_hash): Don't test equality
index 1fbf0cac08e0d6aa72e79c0c4957f27feb47edfe..a26c48b3d3513d2e5e12da1fc95207dce7ec7f75 100644 (file)
@@ -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 44bfc497be16ebc241698a8f2c6b784ed450f1e5..23d8271a0832ac75da8a45d82f71e6ca9b85a2e3 100644 (file)
@@ -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