From 967cf47793f3a66dd3f8637279fe6d891dd2de9f Mon Sep 17 00:00:00 2001 From: Doug Evans Date: Fri, 4 Jun 2010 18:18:28 +0000 Subject: [PATCH] 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. 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 | 9 +++++ gdb/NEWS | 2 + gdb/doc/ChangeLog | 4 ++ gdb/doc/gdb.texinfo | 30 +++++++++++++-- gdb/python/py-prettyprint.c | 5 +++ gdb/python/python-internal.h | 1 + gdb/python/python.c | 2 + gdb/testsuite/ChangeLog | 7 ++++ gdb/testsuite/gdb.python/py-prettyprint.exp | 42 ++++++++++++++++++++- gdb/testsuite/gdb.python/py-prettyprint.py | 5 +++ 10 files changed, 102 insertions(+), 5 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 86e49429cff..727a21d7360 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,12 @@ +2010-06-04 Doug Evans + + 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 * breakpoint.c (update_global_location_list): Fix comment typo. diff --git a/gdb/NEWS b/gdb/NEWS index ad9a0f156a6..61208b12641 100644 --- 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. diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index dc082035fc1..071a409ae36 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,7 @@ +2010-06-04 Doug Evans + + * gdb.texinfo (Python API): New node `Disabling Pretty-Printers'. + 2010-06-03 Doug Evans * gdbint.texinfo (Coding): Add subsection on command names. diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 37278c87ca4..fa7a0ec66bd 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -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 diff --git a/gdb/python/py-prettyprint.c b/gdb/python/py-prettyprint.c index e678898c00b..4d60c96fc91 100644 --- a/gdb/python/py-prettyprint.c +++ b/gdb/python/py-prettyprint.c @@ -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; diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h index bc07b5d070b..5bd2a4bb64e 100644 --- a/gdb/python/python-internal.h +++ b/gdb/python/python-internal.h @@ -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; diff --git a/gdb/python/python.c b/gdb/python/python.c index 0b7b7ba28ce..31880c107a5 100644 --- a/gdb/python/python.c +++ b/gdb/python/python.c @@ -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. */ diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 45e4689bd41..da283b86fc0 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2010-06-04 Doug Evans + + * 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 * gdb.python/py-value.exp (test_value_hash): Don't test equality diff --git a/gdb/testsuite/gdb.python/py-prettyprint.exp b/gdb/testsuite/gdb.python/py-prettyprint.exp index 1fbf0cac08e..a26c48b3d35 100644 --- a/gdb/testsuite/gdb.python/py-prettyprint.exp +++ b/gdb/testsuite/gdb.python/py-prettyprint.exp @@ -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} diff --git a/gdb/testsuite/gdb.python/py-prettyprint.py b/gdb/testsuite/gdb.python/py-prettyprint.py index 44bfc497be1..23d8271a083 100644 --- a/gdb/testsuite/gdb.python/py-prettyprint.py +++ b/gdb/testsuite/gdb.python/py-prettyprint.py @@ -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 -- 2.30.2