xref: /netbsd-src/external/gpl3/gdb/dist/gdb/testsuite/gdb.base/bg-exec-sigint-bp-cond.exp (revision 8e33eff89e26cf71871ead62f0d5063e1313c33a)
1# Copyright 2023-2024 Free Software Foundation, Inc.
2
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 3 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program.  If not, see <http://www.gnu.org/licenses/>.
15
16# Check that sending GDB a SIGINT while handling execution control
17# does not interrupt the execution control.
18
19standard_testfile
20
21if {[build_executable "failed to prepare" $testfile $srcfile debug]} {
22    return -1
23}
24
25# Run the test.  Sets a breakpoint with a condition that sends a
26# SIGINT to GDB, and ensures that that doesn't make the breakpoint hit
27# cause a premature stop.  This emulates pressing Ctrl-C just while
28# GDB is evaluating the breakpoint condition.
29#
30# AFTER_KILL_COND is appended to the breakpoint condition, after "kill
31# -SIGINT $gdb_pid".
32proc test { {after_kill_cond ""} } {
33    clean_restart $::binfile
34
35    if {![runto_main]} {
36	return
37    }
38
39    delete_breakpoints
40
41    set gdb_pid [exp_pid -i [board_info host fileid]]
42
43    # Number of times the breakpoint should be hit before stopping.
44    set num_hits 10
45
46    # A counter used in the breakpoint's condition to ensure that it
47    # causes a stop after NUM_HITS hits.
48    gdb_test "p \$hit_count = 0" " = 0" "reset hit counter"
49
50    # Set a breakpoint with a condition that sends a SIGINT to GDB.  This
51    # emulates pressing Ctrl-C just while GDB is evaluating the breakpoint
52    # condition.
53    gdb_test \
54	"break foo if \$hit_count\+\+ == $num_hits || \$_shell(\"kill -INT $gdb_pid\") != 0 $after_kill_cond" \
55	"Breakpoint .*" \
56	"break foo if <condition>"
57
58    # Number of times we've seen GDB print "Quit" followed by the
59    # prompt.  We should see that exactly $NUM_HITS times.
60    set quit_count 0
61
62    gdb_test_multiple "c&" "SIGINT does not interrupt background execution" {
63	-re "^c&\r\nContinuing\\.\r\n$::gdb_prompt " {
64	    exp_continue
65	}
66	-re "^Quit\r\n$::gdb_prompt " {
67	    incr quit_count
68	    verbose -log "quit_count=$quit_count"
69	    exp_continue
70	}
71	-re "^\r\nBreakpoint .*return 0;" {
72	    gdb_assert {$quit_count == $num_hits} $gdb_test_name
73	}
74	-re ".*Asynchronous execution not supported on this target\..*" {
75	    unsupported "$gdb_test_name (asynchronous execution not supported)"
76	}
77    }
78}
79
80# Test without writing to memory after killing GDB.  This does not
81# take any Python path at the time of writing.
82with_test_prefix "no force memory write" {
83    test
84}
85
86# Writing to memory from the condition makes GDB enter Python for
87# reporting a memory changed event.  Thus this tests that GDB doesn't
88# forward the SIGINT to Python, interrupting Python, causing the
89# breakpoint to prematurely stop like:
90#
91#  c&
92#  Continuing.
93#  (gdb) Error in testing breakpoint condition:
94#  Quit
95#
96with_test_prefix "force memory write" {
97    test " || (global = 0)"
98}
99