summaryrefslogtreecommitdiff
path: root/gdb/testsuite/gdb.base/signals.exp
blob: e0e823276e9ae5193e5aaaefed3f1a9e59649c8f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
# Copyright 1997, 1998, 1999, 2003, 2004, 2007, 2008, 2009, 2010
# 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/>.

if [target_info exists gdb,nosignals] {
    verbose "Skipping signals.exp because of nosignals."
    continue
}

if $tracelevel then {
	strace $tracelevel
}


set testfile signals
set srcfile ${testfile}.c
set binfile ${objdir}/${subdir}/${testfile}
if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
    untested signals.exp
    return -1
}

# Create and source the file that provides information about the compiler
# used to compile the test case.
if [get_compiler_info ${binfile}] {
    return -1;
}

if {$hp_cc_compiler} {
    set void 0
} else {
    set void void
}

gdb_exit
gdb_start

# This will need to be updated as the exact list of signals changes,
# but I want to test that TARGET_SIGNAL_0, TARGET_SIGNAL_DEFAULT, and
# TARGET_SIGNAL_UNKNOWN are skipped.

proc test_handle_all_print {} {
    global timeout
    # Increase timeout and expect input buffer for large output from gdb.
    # Allow blank or TAB as whitespace characters.
    set oldtimeout $timeout
    set timeout [expr "$timeout + 360"]
    verbose "Timeout is now $timeout seconds" 2
    if { ![istarget "*-*-linux*"]
         && ( [istarget "*-*-gnu*"]
              || [istarget "*-*-mach*"] ) } {
	gdb_test "handle all print" "Signal\[ 	\]+Stop\[ 	\]+Print\[ 	\]+Pass to program\[ 	\]+Description\r\nSIGHUP\[ 	\]+Yes\[ 	\]+Yes\[ 	\]+Yes\[ 	\]+Hangup.*SIG63\[ 	\]+Yes\[ 	\]+Yes\[ 	\]+Yes\[ 	\]+Real-time event 63.*EXC_BREAKPOINT\[ 	\]+Yes\[ 	\]+Yes\[ 	\]+Yes\[ 	\]+Breakpoint"
    } else {
	gdb_test "handle all print" "Signal\[ 	\]+Stop\[ 	\]+Print\[ 	\]+Pass to program\[ 	\]+Description\r\nSIGHUP\[ 	\]+Yes\[ 	\]+Yes\[ 	\]+Yes\[ 	\]+Hangup.*SIG63\[ 	\]+Yes\[ 	\]+Yes\[ 	\]+Yes\[ 	\]+Real-time event 63.*"
    }
    set timeout $oldtimeout
    verbose "Timeout restored to $timeout seconds" 2
}
test_handle_all_print

gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load $binfile

if [runto_main] then {

    # Since count is a static variable outside main, runto_main is no
    # guarantee that count will be 0 at this point.

    gdb_test "set variable count = 0" ""

    # Test an inferior function call that takes a signal that hits a
    # breakpoint (with a false condition).  When GDB tries to run the
    # stack dummy, it will hit the breakpoint at handler.  Provided it
    # doesn't lose its cool, this is not a problem, it just has to
    # note that the breakpoint condition is false and keep going.

    # ...setup an always false conditional breakpoint

    gdb_test "break handler if 0" "Breakpoint \[0-9\]+ .*"
    gdb_test "set \$handler_breakpoint_number = \$bpnum" ""

    # ...setup the signal

    gdb_test "next" "signal \\(SIGUSR1.*" "next to signal"
    gdb_test "next" "alarm \\(.*" "next to alarm #1"
    gdb_test "next" "\\+\\+count; /\\* first \\*/" \
	"next to ++count #1"
    sleep 2

    # ...call the function

    gdb_test "p func1 ()" "^p func1 \\(\\)\r\n.\[0-9\]* = $void" \
	"p func1 () #1"

    # ...veryfiy that the cout was updated

    gdb_test "p count" "= 2" "p count #1"

    # Now run the same test but with a breakpoint that does stop.

    # ...set up the breakpoint and signal

    gdb_test "condition \$handler_breakpoint_number" "now unconditional\\."
    gdb_test "next" "alarm \\(.*" "next to alarm #2"
    gdb_test "next" "\\+\\+count; /\\* second \\*/" \
	"next to ++count #2"
    sleep 2

    # ...call the function, which is immediatly interrupted

    gdb_test "p func1 ()" \
"Breakpoint \[0-9\]*, handler.*
The program being debugged stopped while in a function called from GDB.*" \
	"p func1 () #2"

    # ...verify the backtrace

    gdb_test "backtrace" \
	"#0  handler.*#1  .signal handler called.*#2  func1.*#3  .function called from gdb.*#4.*main.*" \
	"backtrace from handler when calling func1"

    # ...and continue (silently returning)

    gdb_test "continue" "Continuing\\."

    # ...and then count should have been incremented

    gdb_test "p count" "= 5" "p count #2"


    # Verify that "info signals" produces reasonable output.

    gdb_test "info signals" "SIGHUP.*SIGINT.*SIGQUIT.*SIGILL.*SIGTRAP.*SIGABRT.*SIGEMT.*SIGFPE.*SIGKILL.*SIGBUS.*SIGSEGV.*SIGSYS.*SIGPIPE.*SIGALRM.*SIGTERM.*SIGURG.*SIGSTOP.*SIGTSTP.*SIGCONT.*SIGCHLD.*SIGTTIN.*SIGTTOU.*SIGIO.*SIGXCPU.*SIGXFSZ.*SIGVTALRM.*SIGPROF.*SIGWINCH.*SIGLOST.*SIGUSR1.*SIGUSR2.*SIGPWR.*SIGPOLL.*SIGWIND.*SIGPHONE.*SIGWAITING.*SIGLWP.*SIGDANGER.*SIGGRANT.*SIGRETRACT.*SIGMSG.*SIGSOUND.*SIGSAK.*SIGPRIO.*SIG33.*SIG34.*SIG35.*SIG36.*SIG37.*SIG38.*SIG39.*SIG40.*SIG41.*SIG42.*SIG43.*SIG44.*SIG45.*SIG46.*SIG47.*SIG48.*SIG49.*SIG50.*SIG51.*SIG52.*SIG53.*SIG54.*SIG55.*SIG56.*SIG57.*SIG58.*SIG59.*SIG60.*SIG61.*SIG62.*SIG63.*Use the \"handle\" command to change these tables.*" \
	"info signals"

    # Verify that "info signal" correctly handles an argument, be it a
    # symbolic signal name, or an integer ID.

    gdb_test "info signal SIGTRAP" \
	"SIGTRAP\[ \t\]*Yes\[ \t\]*Yes\[ \t\]*No\[ \t\]*Trace/breakpoint trap.*" \
	"info signal SIGTRAP"

    gdb_test "info signal 5" \
	"SIGTRAP\[ \t\]*Yes\[ \t\]*Yes\[ \t\]*No\[ \t\]*Trace/breakpoint trap.*" \
	"info signal 5"

    # Verify that "handle" with illegal arguments is gracefully, um,
    # handled.

    gdb_test "handle" \
	"Argument required .signal to handle.*" \
	"handle without arguments"

    gdb_test "handle SIGFOO" \
	"Unrecognized or ambiguous flag word: \"SIGFOO\".*" \
	"handle with bogus SIG"

    gdb_test "handle SIGHUP frump" \
	"Unrecognized or ambiguous flag word: \"frump\".*" \
	"handle SIG with bogus action"

    # Verify that "handle" can take multiple actions per SIG, and that
    # in the case of conflicting actions, that the rightmost action
    # "wins".

    gdb_test "handle SIGHUP print noprint" \
	"SIGHUP\[ \t\]*No\[ \t\]*No\[ \t\]*Yes\[ \t\]*Hangup.*" \
	"handle SIG with multiple conflicting actions"

    # Exercise all the various actions.  (We don't care what the
    # outcome is, this is just to ensure that they all can be parsed.)

    gdb_test "handle SIGHUP print noprint stop nostop ignore noignore pass nopass" \
	"Signal.*" \
	"handle SIG parses all legal actions"

    # Verify that we can "handle" multiple signals at once,
    # interspersed with actions.

    gdb_test "handle SIG63 print SIGILL" \
	"SIGILL\[ \t\]*Yes\[ \t\]*Yes\[ \t\]*Yes\[ \t\]*Illegal instruction.*SIG63\[ \t\]*Yes\[ \t\]*Yes\[ \t\]*Yes\[ \t\]*Real-time event 63.*" \
	"handle multiple SIGs"

    # Verify that "handle" can take a numeric argument for the signal
    # ID, rather than a symbolic name.  (This may not be portable;
    # works for HP-UX.)

    # Also note that this testpoint overrides SIGTRAP, which on HP-UX
    # at least, is used to implement single-steps and breakpoints.
    # Don't expect to run the inferior after this!

    set test "override SIGTRAP"
    gdb_test_multiple "handle 5 nopass" "$test" {
	-re "SIGTRAP is used by the debugger.*Are you sure you want to change it.*y or n.*" {
	    gdb_test "y" \
		"SIGTRAP\[ \t\]*Yes\[ \t\]*Yes\[ \t\]*No\[ \t\]*Trace/breakpoint trap.*" \
		"$test"
	}
    }

    # GDB doesn't seem to allow numeric signal IDs larger than 15.  Verify
    # that restriction.  ??rehrauer: Not sure if this is a feature or a
    # bug, actually.  Why is the range 1-15?

    gdb_test "handle 58" \
	"Only signals 1-15 are valid as numeric signals.*Use \"info signals\" for a list of symbolic signals.*" \
	"invalid signal number rejected"

    # Verify that we can accept a signal ID range (number-number).
    # ??rehrauer: This feature isn't documented on the quick-reference
    # card.

    gdb_test "handle 13-15" \
	"SIGPIPE.*SIGALRM.*SIGTERM.*" \
	"handle multiple SIGs via integer range"

    # Bizarrely enough, GDB also allows you to reverse the range stat,
    # stop IDs.  E.g., "3-1" and "1-3" mean the same thing.  Probably
    # this isn't documented, but the code anticipates it, so we'd best
    # test it...

    gdb_test "handle 15-13" \
	"SIGPIPE.*SIGALRM.*SIGTERM.*" \
	"handle multiple SIGs via reverse integer range"

    # SIGINT is used by the debugger as well.  Verify that we can
    # change our minds about changing it.

    set test "override SIGINT"
    gdb_test_multiple "handle SIGINT nopass" "$test" {
	-re "SIGINT is used by the debugger.*Are you sure you want to change it.*y or n.*" {
	    gdb_test_multiple "n" "$test" {
		-re "Not confirmed, unchanged.*Signal.*$gdb_prompt $"  {
		    # "Signal ..." should not be in the output.
		    fail gdb/8812 "$test"
		}
		-re "Not confirmed, unchanged.*$gdb_prompt $" {
		    pass "$test"
		}
	    }
	}
    }

    # Verify that GDB responds gracefully to the "signal" command with
    # a missing argument.

    gdb_test "signal" \
	"Argument required .signal number..*" \
	"signal without arguments disallowed"
    
    # Verify that we can successfully send a signal other than 0 to
    # the inferior.  (This probably causes the inferior to run away.
    # Be prepared to rerun to main for further testing.)

    gdb_test "signal SIGUSR1" "Breakpoint.*handler.*"
    gdb_test "bt" \
	"#0  handler .*#1  .signal handler called.*\#2 .*main.*" \
	"backtrace for SIGUSR1"
}

return 0