This is the mail archive of the
gdb-cvs@sourceware.org
mailing list for the GDB project.
[binutils-gdb] Throw a "quit" on a KeyboardException in py-framefilter.c
- From: Tom Tromey <tromey at sourceware dot org>
- To: gdb-cvs at sourceware dot org
- Date: 27 Mar 2018 04:05:57 -0000
- Subject: [binutils-gdb] Throw a "quit" on a KeyboardException in py-framefilter.c
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=4ca59a9f3616ba324952632233acc657fffa8be1
commit 4ca59a9f3616ba324952632233acc657fffa8be1
Author: Tom Tromey <tom@tromey.com>
Date: Mon Apr 24 21:47:59 2017 -0600
Throw a "quit" on a KeyboardException in py-framefilter.c
If a C-c comes while the Python code for a frame filter is running, it
will be turned into a Python KeyboardException. It seems good for
this to be treated like a GDB quit, so this patch changes
py-framefilter.c to notice this situation and call throw_quit in this
case.
gdb/ChangeLog
2018-03-26 Tom Tromey <tom@tromey.com>
* python/py-framefilter.c (throw_quit_or_print_exception): New
function.
(gdbpy_apply_frame_filter): Use it.
gdb/testsuite/ChangeLog
2018-03-26 Tom Tromey <tom@tromey.com>
* gdb.python/py-framefilter.exp: Add test for KeyboardInterrupt.
* gdb.python/py-framefilter.py (name_error): New global.
(ErrorInName.function): Use name_error.
Diff:
---
gdb/ChangeLog | 6 ++++++
gdb/python/py-framefilter.c | 21 ++++++++++++++++++---
gdb/testsuite/ChangeLog | 6 ++++++
gdb/testsuite/gdb.python/py-framefilter.exp | 6 ++++++
gdb/testsuite/gdb.python/py-framefilter.py | 6 +++++-
5 files changed, 41 insertions(+), 4 deletions(-)
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 9b29e6e..59d7bb8 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,11 @@
2018-03-26 Tom Tromey <tom@tromey.com>
+ * python/py-framefilter.c (throw_quit_or_print_exception): New
+ function.
+ (gdbpy_apply_frame_filter): Use it.
+
+2018-03-26 Tom Tromey <tom@tromey.com>
+
PR cli/17716:
* python/py-framefilter.c (py_print_type, py_print_value)
(enumerate_args, py_print_args, gdbpy_apply_frame_filter): Use
diff --git a/gdb/python/py-framefilter.c b/gdb/python/py-framefilter.c
index 28d5c37..0662e68 100644
--- a/gdb/python/py-framefilter.c
+++ b/gdb/python/py-framefilter.c
@@ -1305,6 +1305,21 @@ bootstrap_python_frame_filters (struct frame_info *frame,
return iterable.release ();
}
+/* A helper function that will either print an exception or, if it is
+ a KeyboardException, throw a quit. This can only be called when
+ the Python exception is set. */
+
+static void
+throw_quit_or_print_exception ()
+{
+ if (PyErr_ExceptionMatches (PyExc_KeyboardInterrupt))
+ {
+ PyErr_Clear ();
+ throw_quit ("Quit");
+ }
+ gdbpy_print_stack ();
+}
+
/* This is the only publicly exported function in this file. FRAME
is the source frame to start frame-filter invocation. FLAGS is an
integer holding the flags for printing. The following elements of
@@ -1375,7 +1390,7 @@ gdbpy_apply_frame_filter (const struct extension_language_defn *extlang,
initialization error. This return code will trigger a
default backtrace. */
- gdbpy_print_stack ();
+ throw_quit_or_print_exception ();
return EXT_LANG_BT_NO_FILTERS;
}
@@ -1398,7 +1413,7 @@ gdbpy_apply_frame_filter (const struct extension_language_defn *extlang,
{
if (PyErr_Occurred ())
{
- gdbpy_print_stack ();
+ throw_quit_or_print_exception ();
return EXT_LANG_BT_ERROR;
}
break;
@@ -1423,7 +1438,7 @@ gdbpy_apply_frame_filter (const struct extension_language_defn *extlang,
/* Do not exit on error printing a single frame. Print the
error and continue with other frames. */
if (success == EXT_LANG_BT_ERROR)
- gdbpy_print_stack ();
+ throw_quit_or_print_exception ();
}
return success;
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 5537a91..7ba6dd7 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,5 +1,11 @@
2018-03-26 Tom Tromey <tom@tromey.com>
+ * gdb.python/py-framefilter.exp: Add test for KeyboardInterrupt.
+ * gdb.python/py-framefilter.py (name_error): New global.
+ (ErrorInName.function): Use name_error.
+
+2018-03-26 Tom Tromey <tom@tromey.com>
+
PR backtrace/15582:
* gdb.python/py-framefilter.exp: Add "bt hide" test.
diff --git a/gdb/testsuite/gdb.python/py-framefilter.exp b/gdb/testsuite/gdb.python/py-framefilter.exp
index cc31dd5..545bf77 100644
--- a/gdb/testsuite/gdb.python/py-framefilter.exp
+++ b/gdb/testsuite/gdb.python/py-framefilter.exp
@@ -213,6 +213,12 @@ gdb_test_multiple "bt 1" $test {
}
}
+# Now verify that we can see a quit.
+gdb_test_no_output "python name_error = KeyboardInterrupt" \
+ "Change ErrorFilter to throw KeyboardInterrupt"
+gdb_test "bt 1" "Quit" "bt 1 with KeyboardInterrupt"
+
+
# Test with no debuginfo
# We cannot use prepare_for_testing as we have to set the safe-patch
diff --git a/gdb/testsuite/gdb.python/py-framefilter.py b/gdb/testsuite/gdb.python/py-framefilter.py
index 0c3a3a9..46f7522 100644
--- a/gdb/testsuite/gdb.python/py-framefilter.py
+++ b/gdb/testsuite/gdb.python/py-framefilter.py
@@ -134,13 +134,17 @@ class FrameElider ():
def filter (self, frame_iter):
return ElidingIterator (frame_iter)
+# This is here so the test can change the kind of error that is
+# thrown.
+name_error = RuntimeError
+
# A simple decorator that gives an error when computing the function.
class ErrorInName(FrameDecorator):
def __init__(self, frame):
FrameDecorator.__init__(self, frame)
def function(self):
- raise RuntimeError('whoops')
+ raise name_error('whoops')
# A filter that supplies buggy frames. Disabled by default.
class ErrorFilter():