public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [RFA] add support for disabling individual pretty-printers
@ 2010-05-20  7:34 Doug Evans
  2010-05-20 18:04 ` Eli Zaretskii
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Doug Evans @ 2010-05-20  7:34 UTC (permalink / raw)
  To: gdb-patches

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.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [RFA] add support for disabling individual pretty-printers
  2010-05-20  7:34 [RFA] add support for disabling individual pretty-printers Doug Evans
@ 2010-05-20 18:04 ` Eli Zaretskii
  2010-05-20 19:57 ` Doug Evans
  2010-06-02 22:41 ` Tom Tromey
  2 siblings, 0 replies; 5+ messages in thread
From: Eli Zaretskii @ 2010-05-20 18:04 UTC (permalink / raw)
  To: Doug Evans; +Cc: gdb-patches

> Date: Thu, 20 May 2010 00:12:12 -0700 (PDT)
> From: dje@google.com (Doug Evans)
> 
> The approach below uses the presence of an "enabled" attribute
> on the lookup function (or callable object!) to control the
> enabling/disabling.

Thanks.

> +@node Disabling Pretty-Printers
> +@subsubsection Disabling Pretty-Printers

Please put here a @cindex entry for this subject (you can use the
section name, lower-cased, as its text).

> +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.                 ^

A comma missing here.

The patch for the manual is okay with these changes.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [RFA] add support for disabling individual pretty-printers
  2010-05-20  7:34 [RFA] add support for disabling individual pretty-printers Doug Evans
  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
  2 siblings, 1 reply; 5+ messages in thread
From: Doug Evans @ 2010-05-20 19:57 UTC (permalink / raw)
  To: gdb-patches

On Thu, May 20, 2010 at 12:12 AM, Doug Evans <dje@google.com> wrote:
> The approach below uses the presence of an "enabled" attribute
> on the lookup function (or callable object!) to control the
> enabling/disabling.

Of course, it may be sufficient to just turn `print-stack' off.  GDB
currently doesn't print anything when it's off - it should probably
print some (minimal) error message.

There's also the issue of wanting to install a different pretty
printer for a value (e.g. a fixed or development version).  That can
be done by inserting the new lookup-function into the head of the
right pretty-printer list.  Is that preferable to disabling the
printer-being-replaced?  I don't know.

I think it would be useful to be able to list all the installed
pretty-printers - once I had that it was easy to provide a way to
disable/enable them - but if you don't want to go this route, fine.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [RFA] add support for disabling individual pretty-printers
  2010-05-20 19:57 ` Doug Evans
@ 2010-06-02 22:41   ` Tom Tromey
  0 siblings, 0 replies; 5+ messages in thread
From: Tom Tromey @ 2010-06-02 22:41 UTC (permalink / raw)
  To: Doug Evans; +Cc: gdb-patches

>>>>> "Doug" == Doug Evans <dje@google.com> writes:

Doug> I think it would be useful to be able to list all the installed
Doug> pretty-printers - once I had that it was easy to provide a way to
Doug> disable/enable them - but if you don't want to go this route, fine.

It seems like a good feature.

Tom

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [RFA] add support for disabling individual pretty-printers
  2010-05-20  7:34 [RFA] add support for disabling individual pretty-printers Doug Evans
  2010-05-20 18:04 ` Eli Zaretskii
  2010-05-20 19:57 ` Doug Evans
@ 2010-06-02 22:41 ` Tom Tromey
  2 siblings, 0 replies; 5+ messages in thread
From: Tom Tromey @ 2010-06-02 22:41 UTC (permalink / raw)
  To: Doug Evans; +Cc: gdb-patches

>>>>> "Doug" == Doug Evans <dje@google.com> writes:

Doug> As discussed in irc, I'd like to add support for disabling
Doug> individual pretty-printers.  Broken printers do get installed
Doug> and/or the underlying data structures do change with developers
Doug> not always updating the pretty-printer.  When this happens
Doug> the consequences to a user's debugging session can be severe enough
Doug> that IMO we need to do *something*.

I was thinking that we could perhaps automatically disable any printer
that ever throws an exception.

That is pretty drastic though.

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

Doug> Ok to check in?

Yes, thanks.

Tom

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2010-06-02 22:41 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-05-20  7:34 [RFA] add support for disabling individual pretty-printers Doug Evans
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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).