1# Copyright 2012-2020 Free Software Foundation, Inc. 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 16load_lib trace-support.exp 17 18if {[skip_shlib_tests]} { 19 return 0 20} 21if ![gdb_trace_common_supports_arch] { 22 unsupported "no trace-common.h support for arch" 23 return -1 24} 25 26standard_testfile pending.c 27set libfile1 "pendshr1" 28set libfile2 "pendshr2" 29set executable $testfile 30set libsrc1 $srcdir/$subdir/$libfile1.c 31set libsrc2 $srcdir/$subdir/$libfile2.c 32set lib_sl1 [standard_output_file pendshr1.sl] 33set lib_sl2 [standard_output_file pendshr2.sl] 34 35set lib_opts [gdb_target_symbol_prefix_flags] 36 37if { [gdb_compile_shlib $libsrc1 $lib_sl1 $lib_opts] != "" 38 || [gdb_compile_shlib $libsrc2 $lib_sl2 $lib_opts] != ""} { 39 untested "failed to compile shared library" 40 return -1 41} 42 43set exec_opts [list debug shlib=$lib_sl1 shlib_load] 44if { [gdb_compile $srcdir/$subdir/$srcfile $binfile executable $exec_opts] != "" } { 45 untested "failed to compile" 46 return -1 47} 48 49load_lib mi-support.exp 50set MIFLAGS "-i=mi" 51 52# Test when GDB connects to a disconnected stub, existing tracepoints in 53# remote stub can be uploaded to GDB, and GDB emits MI notification if 54# new tracepoints are created. 55 56proc test_reconnect { } { 57 with_test_prefix "reconnect" { 58 59 global gdbserver_reconnect_p 60 global gdb_prompt 61 global executable 62 global lib_sl1 lib_sl2 63 64 set gdbserver_reconnect_p 1 65 if { [info proc gdb_reconnect] == "" } { 66 return 0 67 } 68 69 clean_restart $executable 70 gdb_load_shlib $lib_sl1 71 gdb_load_shlib $lib_sl2 72 if ![runto_main] then { 73 fail "can't run to main" 74 return 0 75 } 76 # Create tracepoints on marker and main, and leave them in the 77 # remote stub. 78 gdb_test "trace marker" "Tracepoint.*at.* file .*" \ 79 "tracepoint on marker" 80 gdb_test "trace main" "Tracepoint.*at.* file .*" \ 81 "tracepoint on main" 82 gdb_test_no_output "tstart" "start trace experiment" 83 84 set test "disconnect" 85 gdb_test_multiple "disconnect" $test { 86 -re "Trace is running but will stop on detach; detach anyway\\? \\(y or n\\) $" { 87 pass $test 88 89 set test "disconnected" 90 gdb_test_multiple "y" $test { 91 -re "$gdb_prompt $" { 92 pass "$test" 93 } 94 } 95 } 96 } 97 98 gdb_exit 99 100 if [mi_gdb_start] { 101 return 102 } 103 104 global srcdir 105 global subdir 106 global binfile 107 108 mi_gdb_reinitialize_dir $srcdir/$subdir 109 mi_gdb_load ${binfile} 110 111 global gdbserver_protocol 112 global gdbserver_gdbport 113 114 # Create tracepoints on marker and pendfunc2. 115 mi_gdb_test "-break-insert -a -f pendfunc2" \ 116 {.*\^done,bkpt=.*addr=\"<PENDING>\".*} \ 117 "insert tracepoint on pendfunc2" 118 mi_gdb_test "-break-insert -a marker" {.*\^done,bkpt=.*\".*} \ 119 "insert tracepoint on marker" 120 121 # Connect to the remote stub again, and make sure GDB merges the 122 # tracepoints of both sides correctly. 123 send_gdb "47-target-select $gdbserver_protocol $gdbserver_gdbport\n" 124 125 global mi_gdb_prompt 126 set test "tracepoint created" 127 gdb_expect { 128 -re "=breakpoint-created,bkpt=\{number=\"1\",type=\"tracepoint\"" { 129 # Tracepoint 1 in GDB, which has already existed before 130 # connecting, should have been merged with a tracepoint on 131 # the target, so we shouldn't see a =breakpoint-created 132 # notification for it. 133 fail "$test: 1" 134 exp_continue 135 } 136 -re "=breakpoint-created,bkpt=\{number=\"2\",type=\"tracepoint\"" { 137 # Similar to above. 138 fail "$test: 2" 139 exp_continue 140 } 141 -re "=breakpoint-created,bkpt=\{number=\"3\",type=\"tracepoint\",disp=\"keep\",enabled=\"y\",\[^\n\]+,func=\"main\"\[^\n\]+,installed=\"y\"" { 142 # A tracepoint on main was defined in the stub, not in GDB, 143 # so we should see a =breakpoint-created notification. 144 pass $test 145 } 146 } 147 # Tracepoint on marker is defined. After the sync, we know that 148 # the tracepoint is in remote stub. Mark it 'installed'. 149 set test "tracepoint on marker is installed" 150 gdb_expect { 151 -re "=breakpoint-modified,bkpt=\{number=\"2\".*,func=\"marker\".*installed=\"y\".*${mi_gdb_prompt}$" { 152 pass "$test" 153 } 154 } 155 # Check that tracepoint 1 is still pending. 156 mi_gdb_test "-break-info 1" \ 157 {.*\^done,BreakpointTable=.*addr=\"<PENDING>\".*} \ 158 "break-info 1" 159 160 set gdbserver_reconnect_p 0 161 } 162} 163 164# Test 'breakpoint-modified' notification is emited when pending tracepoints are 165# resolved. 166 167proc test_pending_resolved { } { 168 with_test_prefix "pending resolved" { 169 global decimal hex 170 global executable 171 global srcdir 172 global subdir 173 global binfile 174 global lib_sl1 lib_sl2 175 global mi_gdb_prompt 176 177 gdb_exit 178 if [mi_gdb_start] { 179 continue 180 } 181 182 mi_gdb_reinitialize_dir $srcdir/$subdir 183 mi_gdb_load ${binfile} 184 mi_load_shlibs $lib_sl1 $lib_sl2 185 186 # Create a pending tracepoint on pendfunc2 187 mi_gdb_test "-break-insert -a -f pendfunc2" \ 188 {.*\^done,bkpt=.*addr=\"<PENDING>\".*} \ 189 "insert breakpoint on pendfunc2" 190 # Insert breakpoint on marker 191 mi_gdb_test "-break-insert marker" {.*\^done,bkpt=.*} \ 192 "insert breakpoint on marker" 193 194 mi_run_cmd 195 mi_expect_stop "breakpoint-hit" "marker" ""\ 196 ".*" ".*" {"" "disp=\"keep\""} \ 197 "continue to marker breakpoint" 198 mi_gdb_test "-trace-start" {\^done} "trace start" 199 200 mi_send_resuming_command "exec-continue" "continuing execution to marker 1" 201 202 # It is expected to get two "=breakpoint-modified" notifications. 203 # Pending tracepoint is resolved. 204 set test "tracepoint on pendfunc2 resolved" 205 gdb_expect { 206 -re "=breakpoint-modified,bkpt=\{number=\"1\",type=\"tracepoint\".*.*times=\"0\".*installed=\"n\"" { 207 pass "$test" 208 } 209 } 210 # Resolved tracepoint is installed. 211 set test "tracepoint on pendfunc2 installed" 212 gdb_expect { 213 -re "=breakpoint-modified,bkpt=\{number=\"1\",type=\"tracepoint\".*.*times=\"0\".*installed=\"y\"" { 214 pass "$test" 215 } 216 } 217 218 mi_expect_stop "breakpoint-hit" "marker" ".*" ".*" ".*" \ 219 {"" "disp=\"keep\""} "continue to marker" 220 221 222 mi_gdb_test "-trace-stop" {\^done,.*} "trace stop" 223 mi_gdb_test "-trace-find frame-number 0" \ 224 "-trace-find frame-number 0\r\n\\^done,found=\"1\",tracepoint=\"${decimal}\",traceframe=\"0\",frame=\{.*" \ 225 "-trace-find frame-number 0" 226 mi_gdb_test "-trace-find none" {\^done,found="0"} "back to live inferior" 227 228 mi_send_resuming_command "exec-continue" "continuing to exit" 229 set test "tracepoint on pendfunc2 becomes pending again" 230 gdb_expect { 231 -re ".*=breakpoint-modified,bkpt=\{number=\"1\",type=\"tracepoint\".*addr=\"<PENDING>\",.*times=\"0\"" { 232 pass "$test" 233 } 234 -re ".*${mi_gdb_prompt}$" { 235 fail $test 236 } 237 timeout { 238 fail "$test (timeout)" 239 } 240 } 241 242 mi_expect_stop "exited-normally" "" "" "" "" "" "" 243 } 244} 245 246# Test target supports tracepoints or not. 247 248clean_restart $executable 249 250gdb_load_shlib $lib_sl1 251gdb_load_shlib $lib_sl2 252 253if ![runto_main] { 254 fail "can't run to main to check for trace support" 255 return -1 256} 257 258if ![gdb_target_supports_trace] { 259 unsupported "current target does not support trace" 260 return -1 261} 262 263gdb_exit 264 265test_reconnect 266 267test_pending_resolved 268 269return 0 270