From: Pedro Alves Date: Thu, 3 Jun 2021 18:39:18 +0000 (+0100) Subject: Test interrupting programs that block SIGINT [gdb/9425, gdb/14559] X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2de900d8ffa0e6149b7add5796fee256f43a9813;p=thirdparty%2Fbinutils-gdb.git Test interrupting programs that block SIGINT [gdb/9425, gdb/14559] This adds a couple testcases that exercise interrupting programs that block SIGINT. One tests a program that uses sigprocmask to mask out SIGINT, and the other tests a program that waits for SIGINT with sigwait. On GNU/Linux, it is currently impossible to interrupt such a program with Ctrl-C, and you can't interrupt it with the "interrupt" command in all-stop mode either. These currently fail, and are suitably kfailed. The rest of the series will fix the fails. Tested on GNU/Linux native, gdbserver, and gdbserver + "maint set target-non-stop on". gdb/testsuite/ChangeLog: yyyy-mm-dd Pedro Alves PR gdb/9425 PR gdb/14559 * gdb.base/sigint-masked-out.c: New file. * gdb.base/sigint-masked-out.exp: New file. * gdb.base/sigint-sigwait.c: New file. * gdb.base/sigint-sigwait.exp: New file. Change-Id: Iddb70c0a2c92550027fccb6f51ecba1292d233c8 --- diff --git a/gdb/testsuite/gdb.base/sigint-masked-out.c b/gdb/testsuite/gdb.base/sigint-masked-out.c new file mode 100644 index 00000000000..dce28182add --- /dev/null +++ b/gdb/testsuite/gdb.base/sigint-masked-out.c @@ -0,0 +1,43 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 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 . */ + +#include +#include + +static void +done () +{ +} + +int +main (int argc, char *argv[]) +{ + int i; + sigset_t sigs; + + alarm (30); + + sigfillset (&sigs); + sigprocmask (SIG_SETMASK, &sigs, NULL); + + done (); + + while (1) + sleep (1); + + return 0; +} diff --git a/gdb/testsuite/gdb.base/sigint-masked-out.exp b/gdb/testsuite/gdb.base/sigint-masked-out.exp new file mode 100644 index 00000000000..0391152e93a --- /dev/null +++ b/gdb/testsuite/gdb.base/sigint-masked-out.exp @@ -0,0 +1,101 @@ +# Copyright 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 . + +# Make sure that we can interrupt an inferior that has all signals +# masked out, including SIGINT, with both Ctrl-C and the "interrupt" +# command. + +standard_testfile + +if {[build_executable "failed to build" $testfile $srcfile {debug}]} { + return -1 +} + +# Test interrupting with Ctrl-C. + +proc_with_prefix test_ctrl_c {} { + global binfile + global gdb_prompt + + clean_restart $binfile + + if ![runto "done"] { + fail "can't run to done function" + return + } + + gdb_test_multiple "continue" "" { + -re "Continuing" { + pass $gdb_test_name + } + } + + after 200 + + send_gdb "\003" + + gdb_test_multiple "" "ctrl-c stops process" { + -timeout 5 + -re -wrap "(received signal SIGINT|stopped).*" { + pass $gdb_test_name + } + timeout { + setup_kfail "gdb/9425" *-*-* + fail "$gdb_test_name (timeout)" + } + } +} + +# Test interrupting with the "interrupt" command. + +proc_with_prefix test_interrupt_cmd {} { + global binfile + global gdb_prompt + + clean_restart $binfile + + if ![runto "done"] { + fail "can't run to done function" + return + } + + gdb_test_multiple "continue&" "" { + -re "Continuing\\.\r\n$gdb_prompt " { + pass $gdb_test_name + } + } + + after 200 + + gdb_test_multiple "interrupt" "" { + -re "$gdb_prompt " { + pass $gdb_test_name + } + } + + gdb_test_multiple "" "interrupt cmd stops process" { + -timeout 5 + -re "(received signal SIGINT|stopped)" { + pass $gdb_test_name + } + timeout { + setup_kfail "gdb/14559" *-*-* + fail "$gdb_test_name (timeout)" + } + } +} + +test_ctrl_c +test_interrupt_cmd diff --git a/gdb/testsuite/gdb.base/sigint-sigwait.c b/gdb/testsuite/gdb.base/sigint-sigwait.c new file mode 100644 index 00000000000..8d1408c5955 --- /dev/null +++ b/gdb/testsuite/gdb.base/sigint-sigwait.c @@ -0,0 +1,80 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 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 . */ + +#include +#include +#include +#include +#include +#include + +static void +handle_sigint (int signo) +{ +} + +static void +done () +{ +} + +int +main (int argc, char **argv) +{ + sigset_t signal_set; + struct sigaction s; + + alarm (30); + + s.sa_flags = SA_RESTART; + s.sa_handler = handle_sigint; + + if (sigaction (SIGINT, &s, NULL) < 0) + { + perror ("<%s> Error sigaction: "); + exit (2); + } + + if (sigfillset (&signal_set) < 0) + { + perror ("
Error sigfillset(): "); + exit (2); + } + + done (); + + while (1) + { + int sig; + + /* Wait for queued signals. .*/ + if (sigwait (&signal_set, &sig) != 0) + { + perror ("
Error sigwait(): "); + exit (1); + } + + /* Process signal. */ + if (sig == SIGINT) + { + printf ("Terminating.\n"); + exit (0); + } + + printf ("Unhandled signal [%s]\n", strsignal (sig)); + } +} diff --git a/gdb/testsuite/gdb.base/sigint-sigwait.exp b/gdb/testsuite/gdb.base/sigint-sigwait.exp new file mode 100644 index 00000000000..1dd706fc1a4 --- /dev/null +++ b/gdb/testsuite/gdb.base/sigint-sigwait.exp @@ -0,0 +1,105 @@ +# Copyright 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 . + +# Make sure that we can interrupt an inferior that has all signals +# masked out, including SIGINT, and then waits for signals with +# sigwait. Test interrupting with both Ctrl-C and the "interrupt" +# command. + +standard_testfile + +if {[build_executable "failed to build" $testfile $srcfile {debug}]} { + return -1 +} + +# Test interrupting with Ctrl-C. + +proc_with_prefix test_ctrl_c {} { + global binfile + global gdb_prompt + + clean_restart $binfile + + if ![runto "done"] { + fail "can't run to done function" + return + } + + gdb_test_multiple "continue" "" { + -re "Continuing" { + pass $gdb_test_name + } + } + + after 200 + + send_gdb "\003" + + global exited_normally_re + + gdb_test_multiple "" "ctrl-c stops process" { + -re -wrap "(received signal SIGINT|stopped).*" { + pass $gdb_test_name + } + -re -wrap "Inferior.*exited normally.*" { + setup_kfail "gdb/9425" *-*-* + fail "$gdb_test_name (the program exited)" + } + } +} + +# Test interrupting with the "interrupt" command. + +proc_with_prefix test_interrupt_cmd {} { + global binfile + global gdb_prompt + + clean_restart $binfile + + if ![runto "done"] { + fail "can't run to done function" + return + } + + gdb_test_multiple "continue&" "" { + -re "Continuing\\.\r\n$gdb_prompt " { + pass $gdb_test_name + } + } + + after 200 + + gdb_test_multiple "interrupt" "" { + -re "$gdb_prompt " { + pass $gdb_test_name + } + } + + global exited_normally_re + + gdb_test_multiple "" "interrupt cmd stops process" { + -timeout 5 + -re "(received signal SIGINT|stopped)" { + pass $gdb_test_name + } + -re "Inferior.*exited normally" { + setup_kfail "gdb/14559" *-*-* + fail "$gdb_test_name (the program exited)" + } + } +} + +test_ctrl_c +test_interrupt_cmd