1#   Copyright 2009-2020 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
16if [target_info exists gdb,nosignals] {
17    verbose "Skipping sigall-reverse.exp because of nosignals."
18    return
19}
20
21if ![supports_reverse] {
22    return
23}
24
25
26gdb_exit
27gdb_start
28gdb_reinitialize_dir $srcdir/$subdir
29
30standard_testfile
31
32if {[build_executable $testfile.exp $testfile $srcfile debug] == -1} {
33    return -1
34}
35
36proc test_one_sig {nextsig} {
37    global sig_supported
38    global gdb_prompt
39    global thissig
40    global record_instruction_kfail
41
42    set this_sig_supported $sig_supported
43    gdb_test "handle SIG$thissig stop print" \
44	"SIG$thissig\[ \t\]*Yes\[ \t\]*Yes\[ \t\]*Yes.*"
45    gdb_test "b handle_$thissig" "Breakpoint \[0-9\]+ .*"
46    gdb_test "b gen_$nextsig" "Breakpoint \[0-9\]+ .*"
47
48    set need_another_continue 1
49    set missed_handler 0
50    if $this_sig_supported then {
51	if { $thissig == "IO" } {
52	    setup_xfail "i*86-pc-linuxoldld-gnu" "i*86-pc-linuxaout-gnu"
53	}
54	gdb_test_multiple "continue" "get signal $thissig" {
55	    -wrap -re \
56		"Program received signal SIG$thissig.*handle_$thissig.*" {
57		fail "$gdb_test_name (wrong location)"
58	    }
59	    -wrap -re "Program received signal SIG$thissig.*" {
60		pass $gdb_test_name
61	    }
62	    -wrap -re "Breakpoint.* handle_$thissig.*" {
63		xfail $gdb_test_name
64		set need_another_continue 0
65	    }
66	    -wrap -re \
67		"Process record does not support instruction 0xfae64 at.*" {
68		kfail "gdb/25038" $gdb_test_name
69		set record_instruction_kfail 1
70		return
71	    }
72	}
73    }
74
75    if $need_another_continue then {
76	if { $thissig == "URG" } {
77	    setup_xfail "i*86-pc-linuxoldld-gnu" "i*86-pc-linuxaout-gnu"
78	}
79        # Either Lynx or GDB screws up on SIGPRIO
80	if { $thissig == "PRIO" } {
81	    setup_xfail "*-*-*lynx*"
82	}
83	set testmsg "send signal $thissig"
84	gdb_test_multiple "continue" $testmsg {
85	    -re "Breakpoint.*handle_$thissig.*$gdb_prompt $" {
86		pass $testmsg
87	    }
88	    -re "Breakpoint.*gen_$nextsig.*kill.*$gdb_prompt $" {
89		fail "missed breakpoint at handle_$thissig"
90		set missed_handler 1
91	    }
92	}
93    }
94
95    if { $missed_handler == "0" } then {
96	set testmsg "advance to $nextsig"
97        gdb_test_multiple "signal 0" $testmsg {
98	    -re "Breakpoint.*gen_$nextsig.*kill.*$gdb_prompt $" {
99	        pass $testmsg
100	        set sig_supported 1
101	    }
102	    -re "Breakpoint.*gen_$nextsig.*handle.*$gdb_prompt $" {
103	        pass $testmsg
104	        set sig_supported 0
105	    }
106        }
107    }
108    set thissig $nextsig
109}
110
111proc test_one_sig_reverse {prevsig} {
112    global gdb_prompt
113
114    gdb_test "reverse-continue" "Breakpoint .* handle_$prevsig.*" \
115	"reverse to handler of $prevsig"
116
117    set saw_signal 0
118    set testmsg "reverse to gen_$prevsig"
119    gdb_test_multiple "reverse-continue" $testmsg {
120	-re "Breakpoint.*handle_.*$gdb_prompt " {
121	    pass "$testmsg (un-handled)"
122	}
123	-re "Program received signal SIG$prevsig.*$gdb_prompt " {
124	    pass "reverse to signal event, $prevsig"
125
126	    set nested_testmsg "reverse signal $prevsig delivered"
127	    gdb_test_multiple "frame" $nested_testmsg {
128		-re ".*handle_$prevsig.*$gdb_prompt " {
129		    fail "$nested_testmsg (wrong location)"
130		}
131		-re ".*$gdb_prompt " {
132		    pass $nested_testmsg
133		}
134	    }
135
136	    set saw_signal 1
137	    send_gdb "reverse-continue\n"
138	    exp_continue
139	}
140	-re "Breakpoint.*kill.*$gdb_prompt " {
141	    if { $saw_signal } then {
142		pass "$testmsg (handled)"
143	    } else {
144		xfail "$testmsg (handled)"
145	    }
146	}
147	-re "No more reverse-execution history.*kill.*$gdb_prompt " {
148	    if { $saw_signal } then {
149		pass "$testmsg (handled)"
150	    } else {
151		xfail "$testmsg (handled)"
152	    }
153	}
154    }
155}
156
157gdb_load $binfile
158
159runto gen_ABRT
160
161if [supports_process_record] {
162    # Activate process record/replay
163    gdb_test_no_output "record" "turn on process record"
164}
165
166# The list of signals that the program generates, in the order they
167# are generated.
168set signals {
169    ABRT
170    HUP
171    QUIT
172    ILL
173    EMT
174    FPE
175    BUS
176    SEGV
177    SYS
178    PIPE
179    ALRM
180    URG
181    TSTP
182    CONT
183    CHLD
184    TTIN
185    TTOU
186    IO
187    XCPU
188    XFSZ
189    VTALRM
190    PROF
191    WINCH
192    LOST
193    USR1
194    USR2
195    PWR
196    POLL
197    WIND
198    PHONE
199    WAITING
200    LWP
201    DANGER
202    GRANT
203    RETRACT
204    MSG
205    SOUND
206    SAK
207    PRIO
208    33
209    34
210    35
211    36
212    37
213    38
214    39
215    40
216    41
217    42
218    43
219    44
220    45
221    46
222    47
223    48
224    49
225    50
226    51
227    52
228    53
229    54
230    55
231    56
232    57
233    58
234    59
235    60
236    61
237    62
238    63
239    TERM
240}
241
242# Make the first signal SIGABRT because it is always supported.
243set sig_supported 1
244set thissig "ABRT"
245
246# test signal handling
247with_test_prefix "sig-test-1" {
248    set record_instruction_kfail 0
249    foreach sig [lrange $signals 1 end] {
250	test_one_sig $sig
251	if { $record_instruction_kfail } {
252	    return -1
253	}
254    }
255}
256
257# The last signal (SIGTERM) gets handled slightly differently because
258# we are not setting up for another test.
259gdb_test "handle SIGTERM stop print" \
260    "SIGTERM\[ \t\]*Yes\[ \t\]*Yes\[ \t\]*Yes.*"
261gdb_test "b handle_TERM" "Breakpoint \[0-9\]+ .*"
262gdb_test "continue" \
263    "Continuing.*Program received signal SIGTERM.*" \
264    "get signal TERM"
265gdb_test "continue" "Breakpoint.*handle_TERM.*" "send signal TERM"
266
267with_timeout_factor 2 {
268    gdb_test "continue" "\[process \[0-9\]+ .*" "continue to signal exit" \
269	"The next instruction is syscall exit_group.* program...y. or n. " \
270	"yes"
271}
272
273foreach sig [lreverse $signals] {
274    test_one_sig_reverse $sig
275}
276
277# Make the first signal SIGABRT because it is always supported.
278set sig_supported 1
279set thissig "ABRT"
280
281with_test_prefix "sig-test-2" {
282    foreach sig [lrange $signals 1 end] {
283	test_one_sig $sig
284    }
285}
286