diff options
author | Tom de Vries <tdevries@suse.de> | 2021-10-19 23:50:50 +0200 |
---|---|---|
committer | Tom de Vries <tdevries@suse.de> | 2021-10-19 23:50:50 +0200 |
commit | c82f680a94399a0f1c9fdc53ed79a8cf333213a6 (patch) | |
tree | 2f8984a012c205b65b357f93be8f5b02a9977dd5 | |
parent | 5a8edb756a56cdfb563006cbc39561994acf6d2d (diff) | |
download | gdb-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.c | 11 | ||||
-rw-r--r-- | gdb/extension.h | 6 | ||||
-rw-r--r-- | gdb/python/python.c | 55 | ||||
-rw-r--r-- | gdb/testsuite/gdb.gdb/python-interrupts.exp | 35 |
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 |