aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom de Vries <tdevries@suse.de>2021-10-19 23:50:50 +0200
committerTom de Vries <tdevries@suse.de>2021-10-19 23:50:50 +0200
commitc82f680a94399a0f1c9fdc53ed79a8cf333213a6 (patch)
tree2f8984a012c205b65b357f93be8f5b02a9977dd5
parent5a8edb756a56cdfb563006cbc39561994acf6d2d (diff)
downloadgdb-c82f680a94399a0f1c9fdc53ed79a8cf333213a6.zip
gdb-c82f680a94399a0f1c9fdc53ed79a8cf333213a6.tar.gz
gdb-c82f680a94399a0f1c9fdc53ed79a8cf333213a6.tar.bz2
[gdb/testsuite] Reimplement gdb.gdb/python-interrupts.exp as unittest
The test-case gdb.gdb/python-interrupts.exp: - runs to captured_command_loop - sets a breakpoint at set_active_ext_lang - calls a python command - verifies the command triggers the breakpoint - sends a signal and verifies the result The test-case is fragile, because (f.i. with -flto) it cannot be guaranteed that captured_command_loop and set_active_ext_lang are available for setting breakpoints. Reimplement the test-case as unittest, using: - execute_command_to_string to capture the output - try/catch to catch the "Error while executing Python code" exception - a new hook selftests::hook_set_active_ext_lang to raise the signal Tested on x86_64-linux.
-rw-r--r--gdb/extension.c11
-rw-r--r--gdb/extension.h6
-rw-r--r--gdb/python/python.c55
-rw-r--r--gdb/testsuite/gdb.gdb/python-interrupts.exp35
4 files changed, 57 insertions, 50 deletions
diff --git a/gdb/extension.c b/gdb/extension.c
index 27dce9b..89ab29f 100644
--- a/gdb/extension.c
+++ b/gdb/extension.c
@@ -682,6 +682,12 @@ install_gdb_sigint_handler (struct signal_handler *previous)
previous->handler_saved = 0;
}
+#if GDB_SELF_TEST
+namespace selftests {
+void (*hook_set_active_ext_lang) () = nullptr;
+}
+#endif
+
/* Set the currently active extension language to NOW_ACTIVE.
The result is a pointer to a malloc'd block of memory to pass to
restore_active_ext_lang.
@@ -708,6 +714,11 @@ install_gdb_sigint_handler (struct signal_handler *previous)
struct active_ext_lang_state *
set_active_ext_lang (const struct extension_language_defn *now_active)
{
+#if GDB_SELF_TEST
+ if (selftests::hook_set_active_ext_lang)
+ selftests::hook_set_active_ext_lang ();
+#endif
+
struct active_ext_lang_state *previous
= XCNEW (struct active_ext_lang_state);
diff --git a/gdb/extension.h b/gdb/extension.h
index 56f5756..2f2ca3e 100644
--- a/gdb/extension.h
+++ b/gdb/extension.h
@@ -319,4 +319,10 @@ extern void get_matching_xmethod_workers
extern gdb::optional<std::string> ext_lang_colorize
(const std::string &filename, const std::string &contents);
+#if GDB_SELF_TEST
+namespace selftests {
+extern void (*hook_set_active_ext_lang) ();
+}
+#endif
+
#endif /* EXTENSION_H */
diff --git a/gdb/python/python.c b/gdb/python/python.c
index 264f7c8..44ec4b7 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -1933,21 +1933,46 @@ test_python ()
output.clear ();
bool saw_exception = false;
- scoped_restore reset_gdb_python_initialized
- = make_scoped_restore (&gdb_python_initialized, 0);
- try
- {
- CMD (output);
- }
- catch (const gdb_exception &e)
- {
- saw_exception = true;
- SELF_CHECK (e.reason == RETURN_ERROR);
- SELF_CHECK (e.error == GENERIC_ERROR);
- SELF_CHECK (*e.message == "Python not initialized");
- }
- SELF_CHECK (saw_exception);
- SELF_CHECK (output.empty ());
+ {
+ scoped_restore reset_gdb_python_initialized
+ = make_scoped_restore (&gdb_python_initialized, 0);
+ try
+ {
+ CMD (output);
+ }
+ catch (const gdb_exception &e)
+ {
+ saw_exception = true;
+ SELF_CHECK (e.reason == RETURN_ERROR);
+ SELF_CHECK (e.error == GENERIC_ERROR);
+ SELF_CHECK (*e.message == "Python not initialized");
+ }
+ SELF_CHECK (saw_exception);
+ SELF_CHECK (output.empty ());
+ }
+
+ saw_exception = false;
+ {
+ scoped_restore save_hook
+ = make_scoped_restore (&hook_set_active_ext_lang,
+ []() { raise (SIGINT); });
+ try
+ {
+ CMD (output);
+ }
+ catch (const gdb_exception &e)
+ {
+ saw_exception = true;
+ SELF_CHECK (e.reason == RETURN_ERROR);
+ SELF_CHECK (e.error == GENERIC_ERROR);
+ SELF_CHECK (*e.message == "Error while executing Python code.");
+ }
+ SELF_CHECK (saw_exception);
+ std::string ref_output("Traceback (most recent call last):\n"
+ " File \"<string>\", line 1, in <module>\n"
+ "KeyboardInterrupt\n");
+ SELF_CHECK (output == ref_output);
+ }
#undef CMD
}
diff --git a/gdb/testsuite/gdb.gdb/python-interrupts.exp b/gdb/testsuite/gdb.gdb/python-interrupts.exp
deleted file mode 100644
index 33cf1ef..0000000
--- a/gdb/testsuite/gdb.gdb/python-interrupts.exp
+++ /dev/null
@@ -1,35 +0,0 @@
-# Copyright 2014-2021 Free Software Foundation, Inc.
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-# Test Python SIGINT handling.
-# This is easiest if we can send SIGINT when gdb is at particular points.
-
-load_lib selftest-support.exp
-load_lib gdb-python.exp
-
-proc test_python_interrupts {} {
- if {[skip_python_tests]} {
- return -1
- }
-
- gdb_breakpoint set_active_ext_lang temporary
- gdb_test "call catch_command_errors(execute_command, \"python print(5)\", 0, true)" \
- "Temporary breakpoint.*silently stop."
- gdb_test "signal SIGINT" \
- "KeyboardInterrupt.*Error while executing Python code."
- return 0
-}
-
-do_self_tests captured_command_loop test_python_interrupts