Automatic Copyright Year update after running gdb/copyright.py
[deliverable/binutils-gdb.git] / gdb / testsuite / gdb.threads / access-mem-running-thread-exit.exp
CommitLineData
88b9d363 1# Copyright (C) 2021-2022 Free Software Foundation, Inc.
05c06f31
PA
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
16# Test that we can access memory while all the threads of the inferior
17# are running, and even if:
18#
19# - the leader thread exits
20# - the selected thread exits
21#
22# This test constantly spawns short lived threads to make sure that on
23# systems with debug APIs that require passing down a specific thread
24# to work with (e.g., GNU/Linux ptrace and /proc filesystem), GDB
25# copes with accessing memory just while the thread it is accessing
26# memory through exits.
27#
28# The test spawns two processes and alternates memory accesses between
29# them to force flushing per-process caches. At the time of writing,
30# the Linux backend accesses inferior memory via /proc/<pid>/mem, and
31# keeps one such file open, as a cache. Alternating inferiors forces
32# opening such file for a different process, which fails if GDB tries
33# to open the file for a thread that exited. The test does ensures
34# those reopen/fail code paths are exercised.
35
36standard_testfile
37
38if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug pthreads}] == -1} {
39 return -1
40}
41
42# The test proper. NON_STOP indicates whether we're testing in
43# non-stop, or all-stop mode.
44
45proc test { non_stop } {
46 global binfile
47 global gdb_prompt
48 global GDBFLAGS
49
50 save_vars { GDBFLAGS } {
51 append GDBFLAGS " -ex \"set non-stop $non_stop\""
52 clean_restart ${binfile}
53 }
54
55 if ![runto_main] {
56 fail "cannot run to main"
57 return -1
58 }
59
60 # If debugging with target remote, check whether the all-stop variant
61 # of the RSP is being used. If so, we can't run the background tests.
62 if {!$non_stop
63 && [target_info exists gdb_protocol]
64 && ([target_info gdb_protocol] == "remote"
65 || [target_info gdb_protocol] == "extended-remote")} {
66
67 gdb_test_multiple "maint show target-non-stop" "" {
68 -wrap -re "(is|currently) on.*" {
69 }
70 -wrap -re "(is|currently) off.*" {
71 unsupported "can't issue commands while target is running"
72 return 0
73 }
74 }
75 }
76
77 delete_breakpoints
78
79 # Start the second inferior.
80 with_test_prefix "second inferior" {
81 gdb_test "add-inferior -no-connection" "New inferior 2.*"
82 gdb_test "inferior 2" "Switching to inferior 2 .*"
83
84 gdb_load $binfile
85
86 if ![runto_main] {
87 fail "cannot run to main"
88 return -1
89 }
90 }
91
92 delete_breakpoints
93
94 # These put too much noise in the logs.
95 gdb_test_no_output "set print thread-events off"
96
97 # Continue all threads of both processes.
98 gdb_test_no_output "set schedule-multiple on"
99 if {$non_stop == "off"} {
100 set cmd "continue &"
101 } else {
102 set cmd "continue -a &"
103 }
104 gdb_test_multiple $cmd "continuing" {
105 -re "Continuing\.\r\n$gdb_prompt " {
106 pass $gdb_test_name
107 }
108 }
109
110 # Like gdb_test, but:
111 # - don't issue a pass on success.
112 # - on failure, clear the ok variable in the calling context, and
113 # break it.
114 proc my_gdb_test {cmd pattern message} {
115 upvar inf inf
116 upvar iter iter
117 if {[gdb_test_multiple $cmd "access mem ($message, inf=$inf, iter=$iter)" {
118 -wrap -re $pattern {
119 }
120 }] != 0} {
121 uplevel 1 {set ok 0}
122 return -code break
123 }
124 }
125
126 # Hammer away for 5 seconds, alternating between inferiors.
127 set ::done 0
128 after 5000 { set ::done 1 }
129
130 set inf 1
131 set ok 1
132 set iter 0
133 while {!$::done && $ok} {
134 incr iter
135 verbose -log "xxxxx: iteration $iter"
136 gdb_test "info threads" ".*" ""
137
138 if {$inf == 1} {
139 set inf 2
140 } else {
141 set inf 1
142 }
143
144 my_gdb_test "inferior $inf" ".*" "inferior $inf"
145
146 my_gdb_test "print global_var = 555" " = 555" \
147 "write to global_var"
148 my_gdb_test "print global_var" " = 555" \
149 "print global_var after writing"
150 my_gdb_test "print global_var = 333" " = 333" \
151 "write to global_var again"
152 my_gdb_test "print global_var" " = 333" \
153 "print global_var after writing again"
154 }
155
156 if {$ok} {
157 pass "access mem"
158 }
159}
160
161foreach non_stop { "off" "on" } {
162 set stop_mode [expr ($non_stop=="off")?"all-stop":"non-stop"]
163 with_test_prefix "$stop_mode" {
164 test $non_stop
165 }
166}
This page took 0.035686 seconds and 4 git commands to generate.