[RFA,03/10] Allow elision of some filtered frames

Message ID 20170425194113.17862-4-tom@tromey.com
State New, archived
Headers

Commit Message

Tom Tromey April 25, 2017, 7:41 p.m. UTC
  When a frame filter elides some frames, they are still printed by
"bt", indented a few spaces.  PR backtrace/15582 notes that it would
be nice for users if elided frames could simply be dropped.  This
patch adds this capability.

ChangeLog
2017-04-25  Tom Tromey  <tom@tromey.com>

	PR backtrace/15582:
	* stack.c (backtrace_command): Parse "elide" argument.
	* python/py-framefilter.c (py_print_frame): Handle PRINT_ELIDE.
	* extension.h (enum frame_filter_flags) <PRINT_ELIDE>: New
	constant.

doc/ChangeLog
2017-04-25  Tom Tromey  <tom@tromey.com>

	PR backtrace/15582:
	* gdb.texinfo (Backtrace): Mention "elide" argument.

testsuite/ChangeLog
2017-04-25  Tom Tromey  <tom@tromey.com>

	PR backtrace/15582:
	* gdb.python/py-framefilter.exp: Add "bt elide" test.
---
 gdb/ChangeLog                               |  8 +++++
 gdb/doc/ChangeLog                           |  5 +++
 gdb/doc/gdb.texinfo                         |  6 ++++
 gdb/extension.h                             |  3 ++
 gdb/python/py-framefilter.c                 | 50 ++++++++++++++---------------
 gdb/stack.c                                 |  2 ++
 gdb/testsuite/ChangeLog                     |  5 +++
 gdb/testsuite/gdb.python/py-framefilter.exp |  3 ++
 8 files changed, 57 insertions(+), 25 deletions(-)
  

Comments

Eli Zaretskii April 26, 2017, 10:34 a.m. UTC | #1
> From: Tom Tromey <tom@tromey.com>
> Cc: Tom Tromey <tom@tromey.com>
> Date: Tue, 25 Apr 2017 13:41:06 -0600
> 
> When a frame filter elides some frames, they are still printed by
> "bt", indented a few spaces.  PR backtrace/15582 notes that it would
> be nice for users if elided frames could simply be dropped.  This
> patch adds this capability.

OK for the documentation part.

Does this warrant a NEWS entry?

Thanks.
  
Phil Muldoon April 28, 2017, 2:50 p.m. UTC | #2
On 25/04/17 20:41, Tom Tromey wrote:
> When a frame filter elides some frames, they are still printed by
> "bt", indented a few spaces.  PR backtrace/15582 notes that it would
> be nice for users if elided frames could simply be dropped.  This
> patch adds this capability.
> 
> ChangeLog
> 2017-04-25  Tom Tromey  <tom@tromey.com>
> 
> 	PR backtrace/15582:
> 	* stack.c (backtrace_command): Parse "elide" argument.
> 	* python/py-framefilter.c (py_print_frame): Handle PRINT_ELIDE.
> 	* extension.h (enum frame_filter_flags) <PRINT_ELIDE>: New
> 	constant.
> 
> doc/ChangeLog
> 2017-04-25  Tom Tromey  <tom@tromey.com>
> 
> 	PR backtrace/15582:
> 	* gdb.texinfo (Backtrace): Mention "elide" argument.

I would have like to have seen these elide/display decisions (whether to show or not to show, whether to show with indention, etc) be made in the frame decorator itself. The decision whether a frame is actually elided or not is made there and it would allowed more flexibility if elided frames were to be displayed on a frame by frame basis. But I'm not sure if this could lead to confusing output. Anyway, it does not matter to much at this point as your patch adds the equivalent of a global override and this other, more intricate functionality, can be added later. I'm curious what you think though.

Patch LGTM.

Cheers

Phil
  
Pedro Alves June 27, 2017, 4:40 p.m. UTC | #3
On 04/25/2017 08:41 PM, Tom Tromey wrote:
> When a frame filter elides some frames, they are still printed by
> "bt", indented a few spaces.  PR backtrace/15582 notes that it would
> be nice for users if elided frames could simply be dropped.  This
> patch adds this capability.
> 

So "bt elide" means "elide the elided frames", not "show me the
elided frames too".  It's fine with me, though I mildly wonder whether
users will be confused by the "double negative".

> diff --git a/gdb/extension.h b/gdb/extension.h
> index 2c79411..7c35502 100644
> --- a/gdb/extension.h
> +++ b/gdb/extension.h
> @@ -100,6 +100,9 @@ enum frame_filter_flags
>  
>      /* Set this flag if frame locals are to be printed.  */
>      PRINT_LOCALS = 8,
> +
> +    /* Set this flag if elided frames should not be printed.  */
> +    PRINT_ELIDE = 32,

Looks like 16 was elided.  :-)

LGTM.

Thanks,
Pedro Alves
  
Tom Tromey June 27, 2017, 8:01 p.m. UTC | #4
>>>>> "Pedro" == Pedro Alves <palves@redhat.com> writes:

>> PRINT_LOCALS = 8,
>> +
>> +    /* Set this flag if elided frames should not be printed.  */
>> +    PRINT_ELIDE = 32,

Pedro> Looks like 16 was elided.  :-)

I had used it in a different patch (which is also still pending).

Tom
  

Patch

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index ab9b432..f68e32c 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,13 @@ 
 2017-04-25  Tom Tromey  <tom@tromey.com>
 
+	PR backtrace/15582:
+	* stack.c (backtrace_command): Parse "elide" argument.
+	* python/py-framefilter.c (py_print_frame): Handle PRINT_ELIDE.
+	* extension.h (enum frame_filter_flags) <PRINT_ELIDE>: New
+	constant.
+
+2017-04-25  Tom Tromey  <tom@tromey.com>
+
 	* stack.c (backtrace_command_1): Remove "show_locals" parameter,
 	add "flags".
 	(backtrace_command): Remove "fulltrace", add "flags".
diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog
index cf2226c..1cdc809 100644
--- a/gdb/doc/ChangeLog
+++ b/gdb/doc/ChangeLog
@@ -1,5 +1,10 @@ 
 2017-04-25  Tom Tromey  <tom@tromey.com>
 
+	PR backtrace/15582:
+	* gdb.texinfo (Backtrace): Mention "elide" argument.
+
+2017-04-25  Tom Tromey  <tom@tromey.com>
+
 	* gdb.texinfo (Backtrace): Describe options individually.
 
 2017-04-21  Simon Marchi  <simon.marchi@ericsson.com>
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index a9f12fd..c30b7b5 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -7225,6 +7225,12 @@  Filter API}, for more information.  Additionally use @ref{disable
 frame-filter all} to turn off all frame filters.  This is only
 relevant when @value{GDBN} has been configured with @code{Python}
 support.
+
+@item backtrace elide
+A Python frame filter might decide to ``elide'' some frames.  Normally
+such elided frames are still printed, but they are indented relative
+to the filtered frames that cause them to be elided.  The @code{elide}
+option causes elided frames to not be printed at all.
 @end table
 
 @kindex where
diff --git a/gdb/extension.h b/gdb/extension.h
index 2c79411..7c35502 100644
--- a/gdb/extension.h
+++ b/gdb/extension.h
@@ -100,6 +100,9 @@  enum frame_filter_flags
 
     /* Set this flag if frame locals are to be printed.  */
     PRINT_LOCALS = 8,
+
+    /* Set this flag if elided frames should not be printed.  */
+    PRINT_ELIDE = 32,
   };
 
 /* A choice of the different frame argument printing strategies that
diff --git a/gdb/python/py-framefilter.c b/gdb/python/py-framefilter.c
index 75b055c..f0474a9 100644
--- a/gdb/python/py-framefilter.c
+++ b/gdb/python/py-framefilter.c
@@ -1238,37 +1238,37 @@  py_print_frame (PyObject *filter, int flags,
 	return EXT_LANG_BT_ERROR;
     }
 
-  {
-    /* Finally recursively print elided frames, if any.  */
-    gdbpy_ref<> elided (get_py_iter_from_func (filter, "elided"));
-    if (elided == NULL)
-      return EXT_LANG_BT_ERROR;
+  if ((flags & PRINT_ELIDE) == 0)
+    {
+      /* Finally recursively print elided frames, if any.  */
+      gdbpy_ref<> elided (get_py_iter_from_func (filter, "elided"));
+      if (elided == NULL)
+	return EXT_LANG_BT_ERROR;
 
-    if (elided != Py_None)
-      {
-	PyObject *item;
+      if (elided != Py_None)
+	{
+	  PyObject *item;
 
-	ui_out_emit_list inner_list_emiter (out, "children");
+	  ui_out_emit_list inner_list_emiter (out, "children");
 
-	if (! out->is_mi_like_p ())
-	  indent++;
+	  if (! out->is_mi_like_p ())
+	    indent++;
 
-	while ((item = PyIter_Next (elided.get ())))
-	  {
-	    gdbpy_ref<> item_ref (item);
+	  while ((item = PyIter_Next (elided.get ())))
+	    {
+	      gdbpy_ref<> item_ref (item);
 
-	    enum ext_lang_bt_status success = py_print_frame (item, flags,
-							      args_type, out,
-							      indent,
-							      levels_printed);
+	      enum ext_lang_bt_status success
+		= py_print_frame (item, flags, args_type, out, indent,
+				  levels_printed);
 
-	    if (success == EXT_LANG_BT_ERROR)
-	      return EXT_LANG_BT_ERROR;
-	  }
-	if (item == NULL && PyErr_Occurred ())
-	  return EXT_LANG_BT_ERROR;
-      }
-  }
+	      if (success == EXT_LANG_BT_ERROR)
+		return EXT_LANG_BT_ERROR;
+	    }
+	  if (item == NULL && PyErr_Occurred ())
+	    return EXT_LANG_BT_ERROR;
+	}
+    }
 
   return EXT_LANG_BT_COMPLETED;
 }
diff --git a/gdb/stack.c b/gdb/stack.c
index b320c93..77e8c9b 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -1890,6 +1890,8 @@  backtrace_command (char *arg, int from_tty)
 	    filters = false;
 	  else if (subset_compare (this_arg, "full"))
 	    flags |= PRINT_LOCALS;
+	  else if (subset_compare (this_arg, "elide"))
+	    flags |= PRINT_ELIDE;
 	  else
 	    {
 	      /* Not a recognized argument, so stop.  */
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index c4d5b79..f9f48c5 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,8 @@ 
+2017-04-25  Tom Tromey  <tom@tromey.com>
+
+	PR backtrace/15582:
+	* gdb.python/py-framefilter.exp: Add "bt elide" test.
+
 2017-04-19  Pedro Alves  <palves@redhat.com>
 
 	* gdb.threads/threadapply.exp (kill_and_remove_inferior): New
diff --git a/gdb/testsuite/gdb.python/py-framefilter.exp b/gdb/testsuite/gdb.python/py-framefilter.exp
index bbec48d..80aa495 100644
--- a/gdb/testsuite/gdb.python/py-framefilter.exp
+++ b/gdb/testsuite/gdb.python/py-framefilter.exp
@@ -157,6 +157,9 @@  gdb_test "bt no-filter full" \
 gdb_test "bt full" \
     ".*#0.*end_func.*str = $hex \"The End\".*st2 = $hex \"Is Near\".*b = 12.*c = 5.*#1.*in funca \\(\\).*#2.*in funcb \\(j=10\\).*bar = \{a = 42, b = 84\}.*#22.*in func1 \\(\\).*#23.*in func2 \\(f=3\\).*elided = $hex \"Elided frame\".*fb = \{nothing = $hex \"Elided Foo Bar\", f = 84, s = 38\}.*bf = $hex.*" \
     "bt full with Reverse disabled"
+gdb_test "bt full elide" \
+    ".*#0.*end_func.*str = $hex \"The End\".*st2 = $hex \"Is Near\".*b = 12.*c = 5.*#1.*in funca \\(\\).*#2.*in funcb \\(j=10\\).*bar = \{a = 42, b = 84\}.*#22.*in func1 \\(\\)\[^#\]*#24.*in func3 \\(i=3\\).*" \
+    "bt full elide with Reverse disabled"
 
 # Test set print frame-arguments
 # none