Automatic Copyright Year update after running gdb/copyright.py
[binutils-gdb.git] / gdb / testsuite / gdb.threads / attach-slow-waitpid.exp
blobb2e5277cff86c65a0776eea858c371fb659f012f
1 # Copyright 2018-2022 Free Software Foundation, Inc.
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.
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.
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/>.
16 # This test script tries to expose a bug in some of the uses of
17 # waitpid in the Linux native support within GDB.  The problem was
18 # spotted on systems which were heavily loaded when attaching to
19 # threaded test programs.  What happened was that during the initial
20 # attach, the loop of waitpid calls that normally received the stop
21 # events from each of the threads in the inferior was not receiving a
22 # stop event for some threads (the kernel just hadn't sent the stop
23 # event yet).
25 # GDB would then trigger a call to stop_all_threads which would
26 # continue to wait for all of the outstanding threads to stop, when
27 # the outstanding stop events finally arrived GDB would then
28 # (incorrectly) discard the stop event, resume the thread, and
29 # continue to wait for the thread to stop.... which it now never
30 # would.
32 # In order to try and expose this issue reliably, this test preloads a
33 # library that intercepts waitpid calls.  All waitpid calls targeting
34 # pid -1 with the WNOHANG flag are rate limited so that only 1 per
35 # second can complete.  Additional calls are forced to return 0
36 # indicating no event waiting.  This is enough to trigger the bug
37 # during the attach phase.
39 # This test only works on Linux
40 if { ![isnative] || [is_remote host] || [use_gdb_stub]
41      || ![istarget *-linux*] } {
42     continue
45 standard_testfile
47 set libfile slow-waitpid
48 set libsrc "${srcdir}/${subdir}/${libfile}.c"
49 set libobj [standard_output_file ${libfile}.so]
51 with_test_prefix "compile preload library" {
52     # Compile the preload library.  We only get away with this as we
53     # limit this test to running when ISNATIVE is true.
54     if { [gdb_compile_shlib_pthreads \
55               $libsrc $libobj {debug}] != "" } then {
56         return -1
57     }
60 with_test_prefix "compile test executable" {
61     # Compile the test program
62     if { [gdb_compile_pthreads \
63               "${srcdir}/${subdir}/${srcfile}" "${binfile}" \
64               executable {debug}] != "" } {
65         return -1
66     }
69 # Spawn GDB with LIB preloaded with LD_PRELOAD.
71 proc gdb_spawn_with_ld_preload {lib} {
72     global env
74     save_vars { env(LD_PRELOAD) } {
75         if { ![info exists env(LD_PRELOAD) ]
76              || $env(LD_PRELOAD) == "" } {
77             set env(LD_PRELOAD) "$lib"
78         } else {
79             append env(LD_PRELOAD) ":$lib"
80         }
82         gdb_start
83     }
86 # Run test program in the background.
87 set test_spawn_id [spawn_wait_for_attach $binfile]
88 set testpid [spawn_id_get_pid $test_spawn_id]
90 # Start GDB with preload library in place.
91 if { [gdb_spawn_with_ld_preload $libobj] == -1 } {
92     # Make sure we get UNTESTED rather than UNRESOLVED.
93     set errcnt 0
94     untested "Couldn't start GDB with preloaded lib"
95     return -1
98 # Load binary, and attach to running program.
99 gdb_load ${binfile}
100 gdb_test "attach $testpid" "Attaching to program.*" "attach to target"
102 gdb_exit
104 # Kill of test program.
105 kill_wait_spawned_process $test_spawn_id