aboutsummaryrefslogtreecommitdiff
path: root/gdb/testsuite/gdb.threads/attach-into-signal.exp
blob: 29197258b3bfc9f61900fb45d73f7ead68879b10 (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
# Copyright 2008-2016 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
}

standard_testfile
set executable_nothr ${testfile}-nothr
set executable_thr ${testfile}-thr

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

    with_test_prefix "$threadtype" {
	clean_restart ${executable}

	set binfile [standard_output_file $executable]
	set escapedbinfile [string_to_regexp ${binfile}]

	if [get_compiler_info] {
	    return -1
	}

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

	set test_spawn_id [spawn_wait_for_attach $binfile]
	set testpid [spawn_id_get_pid $test_spawn_id]

	# 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 } {
	    with_test_prefix "attempt $attempt" {
		set stoppedtry 0
		while { $stoppedtry < 10 } {
		    with_test_prefix "stoppedtry $stoppedtry" {
			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.

			    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

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

	kill_wait_spawned_process $test_spawn_id
    }
}

# 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}" [standard_output_file ${executable_thr}] executable {debug additional_flags=-DUSE_THREADS}] != "" } {
    untested "attach-into-signal.exp (threaded)"
    return -1
}

corefunc threaded ${executable_thr}