xref: /netbsd-src/external/gpl3/gdb/dist/gdb/testsuite/gdb.base/bp-cmds-continue-ctrl-c.exp (revision 7dc3041b3dd6e94fb73609429278b8f58b60359c)
1# Copyright 2017-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# Set a breakpoint with a "continue" command attached, let the
17# inferior hit the breakpoint continuously.  Check that we can use ^C
18# to interrupt the command, and that if ^C is pressed while GDB has
19# the terminal (between the stop and the re-resume), the resulting
20# "Quit" doesn't mess up the debug session.
21
22require {!target_info exists gdb,nosignals}
23
24# This test requires sending ^C to interrupt the running target.
25require {!target_info exists gdb,nointerrupts}
26
27standard_testfile
28
29if {[build_executable "failed to prepare" $testfile $srcfile debug]} {
30    return -1
31}
32
33# See intro.
34
35proc do_test {} {
36    global srcfile binfile
37    global gdb_prompt
38
39    gdb_test "break foo" "Breakpoint .*" "set breakpoint"
40
41    gdb_test \
42	[multi_line_input \
43	     {commands} \
44	     {  c} \
45	     {end}] \
46	"" "commands"
47
48    set test "stop with control-c"
49
50    for {set iter 0} {$iter < 20} {incr iter} {
51
52	# Useful for debugging.
53	#send_user "iter: $iter\n"
54
55	# Consume one breakpoint hit (at least), to make sure that the
56	# continue actually continues between attempts, as opposed to
57	# "c" not actually resuming and then Ctrl-C managing to
58	# interrupt anyway.
59	if {[gdb_test_multiple "continue" "$test (continue)" {
60	    -re "Continuing.*Breakpoint \[^\r\n\]*\r\n" {
61	    }
62	}] != 0} {
63	    return
64	}
65
66	set internal_pass "IPASS: $test (iter $iter)"
67
68	# Breakpoint commands run after the target is considered
69	# stopped, and thus run with GDB owning the terminal.  That
70	# means that it is expected that a Ctrl-C that arrives between
71	#  - GDB reporting the breakpoint hit, and,
72	#  - the breakpoint command continuing the target
73	# results in a Quit.
74
75	after 200 {send_gdb "\003"}
76	if {[gdb_test_multiple "" "$test (unexpected)" {
77	    -re "Program terminated with signal SIGALRM.*\r\n$gdb_prompt $" {
78		fail "$test (SIGALRM)"
79		return
80	    }
81	    -re "Program received signal SIGINT.*\r\n$gdb_prompt $" {
82		send_log "$internal_pass (SIGINT)\n"
83	    }
84	    -re "Quit\r\n$gdb_prompt $" {
85		send_log "$internal_pass (Quit)\n"
86
87		# Check that if we managed to quit somewhere deep in
88		# the unwinders, we can still unwind again.
89		set ok 0
90		gdb_test_multiple "bt" "$internal_pass (bt)" {
91		    -re "#0.*$gdb_prompt $" {
92			send_log "$internal_pass (bt)\n"
93			set ok 1
94		    }
95		}
96		if {!$ok} {
97		    return
98		}
99	    }
100	    -re "Quit\r\n\r\nCommand aborted.\r\n$gdb_prompt $" {
101		send_log "$internal_pass (Command aborted)\n"
102	    }
103	    -re "Breakpoint \[^\r\n\]*$srcfile" {
104		exp_continue
105	    }
106	}] != 0} {
107	    break
108	}
109    }
110
111    gdb_assert {$iter == 20} "stop with control-c"
112}
113
114# With native debugging and "run" (with job control), if the inferior
115# is running, the Ctrl-C reaches the inferior directly, not GDB.  With
116# native debugging and "attach", or with remote debugging, the Ctrl-C
117# reaches GDB first.  So for completeness, try both "run" and
118# "attach".
119
120with_test_prefix "run" {
121    clean_restart $binfile
122
123    if {![runto_main]} {
124	return -1
125    }
126
127    do_test
128}
129
130with_test_prefix "attach" {
131    if {[can_spawn_for_attach]} {
132	clean_restart $binfile
133
134	set test_spawn_id [spawn_wait_for_attach $binfile]
135	set testpid [spawn_id_get_pid $test_spawn_id]
136
137	gdb_test "attach $testpid" "Attaching to.*process $testpid.*" "attach"
138
139	do_test
140
141	kill_wait_spawned_process $test_spawn_id
142    }
143}
144