1# Copyright 2011-2019 Free Software Foundation, Inc. 2# This program is free software; you can redistribute it and/or modify 3# it under the terms of the GNU General Public License as published by 4# the Free Software Foundation; either version 3 of the License, or 5# (at your option) any later version. 6# 7# This program is distributed in the hope that it will be useful, 8# but WITHOUT ANY WARRANTY; without even the implied warranty of 9# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10# GNU General Public License for more details. 11# 12# You should have received a copy of the GNU General Public License 13# along with this program. If not, see <http://www.gnu.org/licenses/>. 14 15load_lib "trace-support.exp" 16 17if {[skip_shlib_tests]} { 18 return 0 19} 20 21standard_testfile 22set executable $testfile 23 24set libipa [get_in_proc_agent] 25 26set lib_opts debug 27 28if [get_compiler_info] { 29 return -1 30} 31 32set additional_flags [list quiet debug shlib=$libipa shlib_load \ 33 "additional_flags=-lust -lurcu-bp" ] 34 35if { [gdb_compile $srcdir/$subdir/$srcfile $binfile executable $additional_flags] != ""} { 36 untested "UST library or headers are not installed" 37 return -1 38} 39 40# Test that the socket file is removed when GDB quits, detaches or 41# resumes the inferior until it exits. 42 43proc strace_remove_socket { action } { 44 with_test_prefix "remove_socket_after_${action}" { 45 46 global executable 47 global gdb_prompt 48 global libipa 49 50 # Restart with a fresh gdb. 51 clean_restart $executable 52 gdb_load_shlib $libipa 53 if ![runto_main] { 54 fail "can't run to main" 55 return -1 56 } 57 58 # List the markers in program. 59 gdb_test "info static-tracepoint-markers" \ 60 ".*ust/bar\[\t \]+n\[\t \]+.*ust/bar2\[\t \]+n\[\t \]+.*" 61 62 set pid "" 63 set test "collect pid" 64 gdb_test_multiple "info inferiors" $test { 65 -re "process (\[-0-9a-fx\]+) \[^\n\]*\n.*${gdb_prompt} $" { 66 set pid $expect_out(1,string) 67 pass $test 68 } 69 -re ".*${gdb_prompt} $" { 70 fail $test 71 } 72 } 73 74 set test "socket file exists" 75 set socket_file "/tmp/gdb_ust${pid}" 76 set status [remote_exec target "sh -c { \[ -S $socket_file \] }"] 77 78 if { [lindex $status 0] == 0 } { 79 pass $test 80 } else { 81 fail $test 82 } 83 84 send_gdb "${action}\n" 85 gdb_expect { 86 -re "A debugging session is active.\r\n.*\r\nQuit anyway\\? \\(y or n\\) $" { 87 send_gdb "y\n" 88 } 89 -re "Detaching .*, process .*$" { 90 } 91 -re "Continuing.*$" { 92 } 93 } 94 95 set exists 1 96 97 for {set i 1} {$i <= 5} {incr i} { 98 set status [remote_exec target "sh -c { \[ -S $socket_file \] }"] 99 if { [lindex $status 0] != 0 } { 100 set exists 0 101 break 102 } 103 sleep 1 104 } 105 106 if { ![is_remote target] && ![string equal $action "detach"] } { 107 setup_kfail gdb/14161 *-*-* 108 } 109 110 set test "socket file removed" 111 112 if { $exists } { 113 fail $test 114 # Since $socket_file is a socket file instead of a regular file, we 115 # can't use 'remote_file target delete $socket_file' here. 116 remote_exec target "sh -c \"rm -r $socket_file\"" 117 } else { 118 pass $test 119 } 120 121 if { [string equal $action "quit"] && [is_remote host] } { 122 global gdb_spawn_id 123 # unset gdb_spawn_id here to avoid sending command 'quit' to GDB 124 # later in default_gdb_exit. 125 unset gdb_spawn_id 126 } 127}} 128 129proc strace_info_marker { } { 130 with_test_prefix "info_marker" { 131 global executable 132 global gdb_prompt 133 global libipa 134 135 # Restart with a fresh gdb. 136 clean_restart $executable 137 gdb_load_shlib $libipa 138 if ![runto_main] { 139 fail "can't run to main" 140 return -1 141 } 142 143 # List the markers in program. They should be disabled. 144 gdb_test "info static-tracepoint-markers" \ 145 ".*ust/bar\[\t \]+n\[\t \]+.*ust/bar2\[\t \]+n\[\t \]+.*" 146 147 # List all the thread. It is expected to get three threads without 148 # any errors. 149 gdb_test_multiple "info threads 3 2 1" "info threads" { 150 -re "3\[ \t\]+Thread .*2\[ \t\]+Thread .*1\[ \t\]+Thread .*${gdb_prompt} $" { 151 pass "info threads" 152 } 153 } 154 155 # GDB detaches inferior so that the socket file can be removed. 156 gdb_test_multiple "detach" "detach" { 157 -re "Detaching .*, process .*${gdb_prompt} $" { 158 pass "detach" 159 } 160 } 161 } 162} 163 164proc strace_probe_marker { } { 165 with_test_prefix "probe_marker" { 166 global executable 167 global expect_out 168 global gdb_prompt 169 global hex 170 global libipa 171 172 # Restart with a fresh gdb. 173 clean_restart $executable 174 gdb_load_shlib $libipa 175 if ![runto_main] { 176 fail "can't run to main" 177 return -1 178 } 179 180 gdb_test "strace -m ust/bar" \ 181 "Static tracepoint \[0-9\]+ at ${hex}: file.*" 182 gdb_test "strace -m ust/bar2" \ 183 "Static tracepoint \[0-9\]+ at ${hex}: file.*" 184 # Two trace markers should be enabled. 185 gdb_test "info static-tracepoint-markers" \ 186 "ust/bar\[\t \]+y\[\t \]+$hex .*ust/bar2\[\t \]+y\[\t \]+$hex.*" 187 188 gdb_breakpoint "end" qualified 189 190 gdb_test_no_output "tstart" 191 gdb_test "continue" "Continuing\\.\[ \r\n\]+Breakpoint.*" \ 192 "continue to end" 193 gdb_test_no_output "tstop" 194 195 gdb_test "tfind" "Found trace frame 0, tracepoint .*" \ 196 "tfind frame 0" 197 gdb_test "tfind" "Found trace frame 1, tracepoint .*" \ 198 "tfind frame 1" 199 gdb_test "tfind" \ 200 "Target failed to find requested trace frame\\..*" 201 } 202} 203 204proc strace_trace_on_same_addr { type } { 205 with_test_prefix "trace_same_addr $type" { 206 global executable 207 global expect_out 208 global gdb_prompt 209 global hex 210 global libipa 211 212 # Restart with a fresh gdb. 213 clean_restart $executable 214 gdb_load_shlib $libipa 215 if ![runto_main] { 216 fail "can't run to main" 217 return -1 218 } 219 220 set marker_bar_addr "" 221 set marker_bar2_addr "" 222 223 # List the markers in program. They should be disabled. 224 gdb_test_multiple "info static-tracepoint-markers" "info static-tracepoint-markers 1" { 225 -re ".*ust/bar\[\t \]+n.*${gdb_prompt} $" { 226 set ignore "" 227 228 regexp "ust/bar\[\t \]+n\[\t \]+($hex) .*ust/bar2\[\t \]+n\[\t \]+($hex) " \ 229 "$expect_out(0,string)" ignore marker_bar_addr marker_bar2_addr 230 231 pass "info static-tracepoint-markers 1" 232 } 233 -re ".*${gdb_prompt} $" { 234 fail "info static-tracepoint-markers 1" 235 } 236 } 237 238 gdb_test "strace -m ust/bar" "Static tracepoint \[0-9\]+ at ${hex}: file.*" 239 gdb_test "strace -m ust/bar2" "Static tracepoint \[0-9\]+ at ${hex}: file.*" 240 # Two trace markers should be enabled. 241 gdb_test "info static-tracepoint-markers" \ 242 "ust/bar\[\t \]+y\[\t \]+$hex .*ust/bar2\[\t \]+y\[\t \]+$hex.*" \ 243 "info static-tracepoint-markers 2" 244 245 # Set breapoints or tracepoints. 246 set test "${type} on marker bar" 247 gdb_test_multiple "${type} *${marker_bar_addr}" $test { 248 -re "\(Fast trace|Trace|Break\)point \[0-9\]+ at ${hex}: file.*\r\n$gdb_prompt $" { 249 pass $test 250 } 251 -re ".*\r\n$gdb_prompt $" { 252 if [string equal $type "ftrace"] { 253 # The instruction may be not long enough to set a fast 254 # tracepoint. Skip the rest of this test. 255 return -1 256 } else { 257 fail $test 258 } 259 } 260 } 261 set test "${type} on marker bar2" 262 gdb_test_multiple "${type} *${marker_bar2_addr}" $test { 263 -re "\(Fast trace|Trace|Break\)point \[0-9\]+ at ${hex}: file.*" { 264 pass $test 265 } 266 -re ".*\r\n$gdb_prompt $" { 267 if [string equal $type "ftrace"] { 268 # The instruction may be not long enough to set a fast 269 # tracepoint. Skip the rest of this test. 270 return -1 271 } else { 272 fail $test 273 } 274 } 275 } 276 277 gdb_breakpoint "end" qualified 278 279 if [string equal $type "break"] { 280 gdb_test "continue" "Continuing\\.\[ \r\n\]+Breakpoint.*" \ 281 "continue to bar" 282 gdb_test "continue" "Continuing\\.\[ \r\n\]+Breakpoint.*" \ 283 "continue to bar2" 284 gdb_test "continue" "Continuing\\.\[ \r\n\]+Breakpoint.*" \ 285 "continue to end" 286 } else { 287 288 gdb_test_no_output "tstart" 289 gdb_test "continue" "Continuing\\.\[ \r\n\]+Breakpoint.*" \ 290 "continue to end" 291 gdb_test_no_output "tstop" 292 293 gdb_test "tfind" "Found trace frame 0, tracepoint .*" \ 294 "tfind frame 0" 295 gdb_test "tfind" "Found trace frame 1, tracepoint .*" \ 296 "tfind frame 1" 297 gdb_test "tfind" "Found trace frame 2, tracepoint .*" \ 298 "tfind frame 2" 299 gdb_test "tfind" "Found trace frame 3, tracepoint .*" \ 300 "tfind frame 3" 301 gdb_test "tfind" \ 302 "Target failed to find requested trace frame\\..*" 303 } 304 } 305} 306 307proc strace_trace_on_diff_addr { } { 308 with_test_prefix "trace_diff_addr" { 309 310 global executable 311 global expect_out 312 global gdb_prompt 313 global hex 314 global libipa 315 316 # Restart with a fresh gdb. 317 clean_restart $executable 318 gdb_load_shlib $libipa 319 if ![runto_main] { 320 fail "can't run to main" 321 return -1 322 } 323 324 set marker_bar_addr "" 325 set marker_bar2_addr "" 326 327 # List the markers in program. They should be disabled. 328 gdb_test_multiple "info static-tracepoint-markers" "info static-tracepoint-markers 1" { 329 -re ".*ust/bar\[\t \]+n.*${gdb_prompt} $" { 330 set ignore "" 331 332 regexp "ust/bar\[\t \]+n\[\t \]+($hex) .*ust/bar2\[\t \]+n\[\t \]+($hex) " \ 333 "$expect_out(0,string)" ignore marker_bar_addr marker_bar2_addr 334 335 pass "info static-tracepoint-markers 1" 336 } 337 -re ".*${gdb_prompt} $" { 338 fail "info static-tracepoint-markers 1" 339 } 340 } 341 342 gdb_test "strace -m ust/bar" "Static tracepoint \[0-9\]+ at ${hex}: file.*" 343 344 gdb_test "info static-tracepoint-markers" \ 345 "ust/bar\[\t \]+y\[\t \]+$hex .*ust/bar2\[\t \]+n\[\t \]+$hex.*" \ 346 "info static-tracepoint-markers 2" 347 348 349 # Set common tracepoint. 350 gdb_test "trace *${marker_bar2_addr}" \ 351 "Tracepoint \[0-9\]+ at ${hex}: file.*" 352 353 gdb_breakpoint "end" qualified 354 355 gdb_test_no_output "tstart" 356 gdb_test "continue" "Continuing\\.\[ \r\n\]+Breakpoint.*" \ 357 "continue to end" 358 gdb_test_no_output "tstop" 359 360 gdb_test "tfind" "Found trace frame 0, tracepoint .*" \ 361 "tfind frame 0" 362 gdb_test "tfind" "Found trace frame 1, tracepoint .*" \ 363 "tfind frame 1" 364 gdb_test "tfind" \ 365 "Target failed to find requested trace frame\\..*" 366 } 367} 368 369# Run it on x86/x86_64 linux. 370if { [istarget "x86_64-*-linux*"] || [istarget "i\[34567\]86-*-linux*"] } { 371 strace_info_marker 372 strace_remove_socket "quit" 373 strace_remove_socket "detach" 374 strace_remove_socket "continue" 375} 376 377clean_restart $executable 378gdb_load_shlib $libipa 379if ![runto_main] { 380 fail "can't run to main to check for trace support" 381 return -1 382} 383if { ![gdb_target_supports_trace] } then { 384 # At this point, the socket file has been created. We must make sure it is 385 # removed when we return here. GDB detaches inferior so that the socket 386 # file can be removed. Note that GDB simply kill inferior doesn't remove 387 # the socket file. 388 gdb_test "detach" "Detaching .*, process .*" 389 unsupported "current target does not support trace" 390 return -1 391} 392 393# Double-check that marker ID ("-m") is not mistaken for an explicit location 394# flag. 395gdb_test "strace -m gdbfoobarbaz" \ 396 "No known static tracepoint marker named gdbfoobarbaz" 397 398strace_probe_marker 399 400strace_trace_on_same_addr "trace" 401strace_trace_on_same_addr "ftrace" 402strace_trace_on_same_addr "break" 403strace_trace_on_diff_addr 404