[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.
This commit is contained in:
parent
5a8edb756a
commit
c82f680a94
4 changed files with 57 additions and 50 deletions
|
@ -682,6 +682,12 @@ install_gdb_sigint_handler (struct signal_handler *previous)
|
||||||
previous->handler_saved = 0;
|
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.
|
/* Set the currently active extension language to NOW_ACTIVE.
|
||||||
The result is a pointer to a malloc'd block of memory to pass to
|
The result is a pointer to a malloc'd block of memory to pass to
|
||||||
restore_active_ext_lang.
|
restore_active_ext_lang.
|
||||||
|
@ -708,6 +714,11 @@ install_gdb_sigint_handler (struct signal_handler *previous)
|
||||||
struct active_ext_lang_state *
|
struct active_ext_lang_state *
|
||||||
set_active_ext_lang (const struct extension_language_defn *now_active)
|
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
|
struct active_ext_lang_state *previous
|
||||||
= XCNEW (struct active_ext_lang_state);
|
= XCNEW (struct active_ext_lang_state);
|
||||||
|
|
||||||
|
|
|
@ -319,4 +319,10 @@ extern void get_matching_xmethod_workers
|
||||||
extern gdb::optional<std::string> ext_lang_colorize
|
extern gdb::optional<std::string> ext_lang_colorize
|
||||||
(const std::string &filename, const std::string &contents);
|
(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 */
|
#endif /* EXTENSION_H */
|
||||||
|
|
|
@ -1933,21 +1933,46 @@ test_python ()
|
||||||
output.clear ();
|
output.clear ();
|
||||||
|
|
||||||
bool saw_exception = false;
|
bool saw_exception = false;
|
||||||
scoped_restore reset_gdb_python_initialized
|
{
|
||||||
= make_scoped_restore (&gdb_python_initialized, 0);
|
scoped_restore reset_gdb_python_initialized
|
||||||
try
|
= make_scoped_restore (&gdb_python_initialized, 0);
|
||||||
{
|
try
|
||||||
CMD (output);
|
{
|
||||||
}
|
CMD (output);
|
||||||
catch (const gdb_exception &e)
|
}
|
||||||
{
|
catch (const gdb_exception &e)
|
||||||
saw_exception = true;
|
{
|
||||||
SELF_CHECK (e.reason == RETURN_ERROR);
|
saw_exception = true;
|
||||||
SELF_CHECK (e.error == GENERIC_ERROR);
|
SELF_CHECK (e.reason == RETURN_ERROR);
|
||||||
SELF_CHECK (*e.message == "Python not initialized");
|
SELF_CHECK (e.error == GENERIC_ERROR);
|
||||||
}
|
SELF_CHECK (*e.message == "Python not initialized");
|
||||||
SELF_CHECK (saw_exception);
|
}
|
||||||
SELF_CHECK (output.empty ());
|
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
|
#undef CMD
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
Loading…
Add table
Add a link
Reference in a new issue