summaryrefslogtreecommitdiff
path: root/gdb/testsuite/gdb.threads/attach-into-signal.exp
blob: e072e51905f18831d30fd79ac3507c61ab50c721 (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
# Copyright 2008-2012 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/>.

# This test was created by modifying attach-stopped.exp.
# This file was created by Jan Kratochvil <jan.kratochvil@redhat.com>.

# This test only works on Linux
if { ![isnative] || [is_remote host] || [target_info exists use_gdb_stub]
     || ![istarget *-linux*] } {
    continue
}

set testfile "attach-into-signal"
set srcfile  ${testfile}.c
set executable_nothr ${testfile}-nothr
set executable_thr ${testfile}-thr

remote_exec build "rm -f ${objdir}/${subdir}/${executable_nothr}"
remote_exec build "rm -f ${objdir}/${subdir}/${executable_thr}"
# For debugging this test
#
#log_user 1

proc corefunc { threadtype executable } {
    global srcfile
    global srcdir
    global objdir
    global subdir
    global gdb_prompt
    global pf_prefix

    set save_pf_prefix $pf_prefix
    lappend pf_prefix "$threadtype:"

    clean_restart ${executable}

    set binfile ${objdir}/${subdir}/${executable}
    set escapedbinfile [string_to_regexp ${objdir}/${subdir}/${executable}]

    if [get_compiler_info ${binfile}] {
	set pf_prefix $save_pf_prefix
	return -1
    }

    gdb_test "handle SIGALRM stop print pass" "Yes.*Yes.*Yes.*"

    # Start the program running and then wait for a bit, to be sure
    # that it can be attached to.
    # Statistically there is a better chance without giving process a nice.

    set testpid [eval exec $binfile &]
    exec sleep 2

    # Run 2 passes of the test.
    # The C file inferior stops pending its signals if a single one is lost,
    # we test successful redelivery of the caught signal by the 2nd pass.

    # linux-2.6.20.4.x86_64 had maximal attempt # 20 in 4 test runs.
    set attempts 100
    set attempt 1
    set passes 1
    while { $passes < 3 && $attempt <= $attempts } {
	set stoppedtry 0
	while { $stoppedtry < 10 } {
	    if [catch {open /proc/${testpid}/status r} fileid] {
		set stoppedtry 10
		break
	    }
	    gets $fileid line1;
	    gets $fileid line2;
	    close $fileid;

	    if {![string match "*(stopped)*" $line2]} {
		# No PASS message as we may be looping in multiple attempts.
		break
	    }
	    sleep 1
	    set stoppedtry [expr $stoppedtry + 1]
	}
	if { $stoppedtry >= 10 } {
	    verbose -log $line2
	    set test "process is still running on the attempt # $attempt of $attempts"
	    break
	}

	# Main test:
	set test "attach (pass $passes), pending signal catch"
	if {[gdb_test_multiple "attach $testpid" $test {
	    -re "Attaching to program.*`?$escapedbinfile'?, process $testpid.*Program received signal SIGALRM.*$gdb_prompt $" {
		# nonthreaded:
		pass $test
		verbose -log "$test succeeded on the attempt # $attempt of $attempts"
		set passes [expr $passes + 1]
	    }
	    -re "Attaching to program.*`?$escapedbinfile'?, process $testpid.*$gdb_prompt $" {
		set ok 0

		if { $threadtype == "threaded" } {
		    # In the threaded case, the signal is left pending
		    # on the second thread.  Check for that by peeking
		    # at the thread's siginfo.  SIGALRM is 14, SIGSTOP
		    # is 19.

		    # With remote targets, we need to pull the thread
		    # list explicitly before GDB even knows about
		    # thread 2.
		    set test2 "pull thread list"
		    gdb_test_multiple "info threads" $test2 {
			-re "\r\n$gdb_prompt $" {
			}
		    }

		    set test2 "thread apply 2 print \$_siginfo.si_signo"
		    gdb_test_multiple $test2 $test2 {
			-re " = 14\r\n$gdb_prompt $" {
			    set ok 1
			}
			-re " = 19\r\n$gdb_prompt $" {
			}
		    }
		} else {
		    # In the nonthreaded case, GDB should tell the
		    # user about having seen a signal.
		}

		if { $ok == 0} {
		    # We just lack the luck, we should try it again.
		    set attempt [expr $attempt + 1]
		} else {
		    pass $test
		    verbose -log "$test succeeded on the attempt # $attempt of $attempts"
		    set passes [expr $passes + 1]
		}
	    }
	}] != 0 } {
	    break
	}

	gdb_test "detach" "Detaching from.*" ""
    }
    if {$passes < 3} {
	if {$attempt > $attempts} {
	    unresolved $test
	} else {
	    fail $test
	}
    }

    # Exit and detach the process.
       
    gdb_exit

    # Make sure we don't leave a process around to confuse
    # the next test run (and prevent the compile by keeping
    # the text file busy), in case the "set should_exit" didn't
    # work.

    # Continue the program - some Linux kernels need it before -9 if the
    # process is stopped.
    remote_exec build "kill -s CONT ${testpid}"
       
    remote_exec build "kill -9 ${testpid}"

    set pf_prefix $save_pf_prefix
}

# build the test case first without threads
#
if {[build_executable $testfile $executable_nothr $srcfile] == -1} {
    untested "attach-into-signal.exp (nonthreaded)"
    return -1
}

corefunc nonthreaded ${executable_nothr}

# build the test case also with threads
#
if  { [gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${objdir}/${subdir}/${executable_thr}" executable {debug additional_flags=-DUSE_THREADS}] != "" } {
    untested "attach-into-signal.exp (threaded)"
    return -1
}

corefunc threaded ${executable_thr}