1# Copyright 2011-2020 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 21if ![gdb_trace_common_supports_arch] { 22 unsupported "no trace-common.h support for arch" 23 return -1 24} 25 26standard_testfile 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 $libfile1.sl] 33set lib_sl2 [standard_output_file $libfile2.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 49clean_restart $executable 50 51gdb_load_shlib $lib_sl1 52gdb_load_shlib $lib_sl2 53 54if ![runto_main] { 55 fail "can't run to main to check for trace support" 56 return -1 57} 58 59if ![gdb_target_supports_trace] { 60 unsupported "current target does not support trace" 61 return -1 62} 63 64# Verify pending tracepoint is resolved to running to main. 65 66proc pending_tracepoint_resolved { trace_type } { 67 with_test_prefix "$trace_type resolved" { 68 global srcdir 69 global subdir 70 global binfile 71 global srcfile 72 global lib_sl1 73 74 # Start with a fresh gdb. 75 gdb_exit 76 gdb_start 77 gdb_reinitialize_dir $srcdir/$subdir 78 79 gdb_test_multiple "$trace_type set_point1" "set pending tracepoint" { 80 -re ".*Make \(fast |\)tracepoint pending.*y or \\\[n\\\]. $" { 81 gdb_test "y" "\(Fast t|T\)racepoint.*set_point1.*pending." \ 82 "set pending tracepoint (without symbols)" 83 } 84 } 85 86 gdb_test "info trace" \ 87 "Num Type\[ \]+Disp Enb Address\[ \]+What.* 88\[0-9\]+\[\t \]+\(fast |\)tracepoint\[ \]+keep y.*PENDING.*set_point1.*" \ 89 "single pending tracepoint info (without symbols)" 90 91 gdb_load ${binfile} 92 93 gdb_test "break main" "Breakpoint.*at.* file .*$srcfile, line.*" \ 94 "breakpoint function" 95 96 gdb_run_cmd 97 gdb_test "" "Breakpoint 2, main.*" 98 99 # Run to main which should resolve a pending tracepoint 100 gdb_test "info trace" \ 101 "Num Type\[ \]+Disp Enb Address\[ \]+What.* 102\[0-9\]+\[\t \]+\(fast |\)tracepoint\[ \]+keep y.*pendfunc.*" \ 103 "single tracepoint info" 104 } 105} 106 107# Verify pending tracepoint is resolved and works as expected. 108 109proc pending_tracepoint_works { trace_type } { 110 with_test_prefix "$trace_type works" { 111 global executable 112 global srcfile 113 global lib_sl1 114 global gdb_prompt 115 116 # Restart with a fresh gdb. 117 clean_restart $executable 118 119 # Test setting and querying pending tracepoints 120 121 gdb_test_multiple "$trace_type set_point1" "set pending tracepoint" { 122 -re ".*Make \(fast |\)tracepoint pending.*y or \\\[n\\\]. $" { 123 gdb_test "y" \ 124 "\(Fast t|T\)racepoint.*set_point1.*pending." \ 125 "set pending tracepoint" 126 } 127 } 128 129 gdb_test "info trace" \ 130 "Num Type\[ \]+Disp Enb Address\[ \]+What.* 131\[0-9\]+\[\t \]+\(fast |\)tracepoint\[ \]+keep y.*PENDING.*set_point1.*" \ 132 "single pending tracepoint info" 133 134 # Run to main which should resolve a pending tracepoint 135 gdb_test "break main" "Breakpoint.*at.* file .*$srcfile, line.*" \ 136 "breakpoint function" 137 gdb_run_cmd 138 gdb_test "" "Breakpoint 2, main.*" 139 140 gdb_test "break marker" "Breakpoint.*at.* file .*$srcfile, line.*" \ 141 "breakpoint on marker" 142 143 set test "start trace experiment" 144 gdb_test_multiple "tstart" $test { 145 -re "^tstart\r\n$gdb_prompt $" { 146 pass $test 147 } 148 -re "Target returns error code .* too far .*$gdb_prompt $" { 149 if [string equal $trace_type "ftrace"] { 150 # The target was unable to install the fast tracepoint 151 # (e.g., jump pad too far from tracepoint). 152 pass "$test (too far)" 153 # Skip the rest of the tests. 154 return 155 } else { 156 fail $test 157 } 158 } 159 160 } 161 162 gdb_test "continue" "Continuing.\r\n\r\n(Thread .* hit )?Breakpoint.*marker.*at.*$srcfile.*" \ 163 "continue to marker" 164 165 gdb_test "tstop" "\[\r\n\]+" "stop trace experiment" 166 167 gdb_test "tfind start" "#0 .*" "tfind test frame 0" 168 gdb_test "tfind" "Found trace frame 1, tracepoint 1.*" \ 169 "tfind test frame 1" 170 gdb_test "tfind" "Found trace frame 2, tracepoint 1.*" \ 171 "tfind test frame 2" 172 gdb_test "tfind" \ 173 "Target failed to find requested trace frame..*" \ 174 "tfind test frame" 175 } 176} 177 178# Verify pending tracepoint is resolved during trace. 179 180proc pending_tracepoint_resolved_during_trace { trace_type } \ 181{ with_test_prefix "$trace_type resolved_in_trace" \ 182{ 183 global executable 184 global srcfile 185 global gdb_prompt 186 global lib_sl1 187 188 # Start with a fresh gdb. 189 clean_restart $executable 190 if ![runto_main] { 191 fail "can't run to main" 192 return -1 193 } 194 195 gdb_test_multiple "$trace_type set_point2" "set pending tracepoint on set_point2" { 196 -re ".*Make \(fast |\)tracepoint pending.*y or \\\[n\\\]. $" { 197 gdb_test "y" "\(Fast t|T\)racepoint.*set_point2.*pending." \ 198 "set pending tracepoint (without symbols)" 199 } 200 } 201 202 gdb_test "info trace" \ 203 "Num Type\[ \]+Disp Enb Address\[ \]+What.* 204\[0-9\]+\[\t \]+\(fast |\)tracepoint\[ \]+keep y.*PENDING.*set_point2.*" \ 205 "single pending tracepoint on set_point2" 206 207 gdb_test "break marker" "Breakpoint.*at.* file .*$srcfile, line.*" \ 208 "breakpoint on marker" 209 210 gdb_test_no_output "tstart" "start trace experiment" 211 212 gdb_test "continue" "Continuing.\r\n\r\n(Thread .* hit )?Breakpoint.*marker.*at.*pending.c.*" \ 213 "continue to marker 1" 214 215 set test "continue to marker 2" 216 gdb_test_multiple "continue" $test { 217 -re "Target returns error code .* too far .*$gdb_prompt $" { 218 if [string equal $trace_type "ftrace"] { 219 # Expected if the target was unable to install the 220 # fast tracepoint (e.g., jump pad too far from 221 # tracepoint). 222 pass "$test (too far)" 223 # Skip the rest of the tests. 224 return 225 } else { 226 fail $test 227 } 228 } 229 -re "Continuing.\r\n(Reading .* from remote target...\r\n)?\r\n(Thread .* hit )?Breakpoint.*marker.*at.*$srcfile.*$gdb_prompt $" { 230 pass $test 231 } 232 } 233 234 gdb_test "tstop" "\[\r\n\]+" "stop trace experiment" 235 236 # tracepoint should be resolved. 237 gdb_test "info trace" \ 238 "Num Type\[ \]+Disp Enb Address\[ \]+What.* 239\[0-9\]+\[\t \]+\(fast |\)tracepoint\[ \]+keep y.*pendfunc2.*" \ 240 "tracepoint is resolved" 241 242 gdb_test "tfind start" "#0 .*" "tfind test frame 0" 243 gdb_test "tfind" "Target failed to find requested trace frame..*" "tfind test frame" 244}} 245 246# Verify pending tracepoint is resolved and installed during trace. 247 248proc pending_tracepoint_installed_during_trace { trace_type } \ 249{ with_test_prefix "$trace_type installed_in_trace" \ 250{ 251 global executable 252 global srcfile 253 global lib_sl1 254 global gdb_prompt 255 global hex 256 257 # Start with a fresh gdb. 258 clean_restart $executable 259 if ![runto_main] { 260 fail "can't run to main" 261 return -1 262 } 263 264 gdb_test "next" ".*" 265 gdb_test "trace main" "Tracepoint \[0-9\] at .*" "set tracepoint on main" 266 267 gdb_test "break marker" "Breakpoint.*at.* file .*$srcfile, line.*" \ 268 "breakpoint on marker" 269 270 gdb_test_no_output "tstart" "start trace experiment" 271 272 gdb_test "continue" "Continuing.\r\n\r\n(Thread .* hit )?Breakpoint.*marker.*at.*${srcfile}.*" \ 273 "continue to marker 1" 274 275 # Set a pending tracepoint during a tracing experiment. 276 gdb_test_multiple "$trace_type set_point2" "set pending tracepoint on set_point2" { 277 -re ".*Make \(fast |\)tracepoint pending.*y or \\\[n\\\]. $" { 278 gdb_test "y" "\(Fast t|T\)racepoint.*set_point2.*pending." \ 279 "set pending tracepoint" 280 } 281 } 282 283 gdb_test "info trace" \ 284 "Num Type\[ \]+Disp Enb Address\[ \]+What.* 285\[0-9\]+\[\t \]+\(fast |\)tracepoint\[ \t\]+keep y.*PENDING.*set_point2.*" \ 286 "single pending tracepoint on set_point2" 287 288 set test "continue to marker 2" 289 gdb_test_multiple "continue" $test { 290 -re "Target returns error code .* too far .*$gdb_prompt $" { 291 if [string equal $trace_type "ftrace"] { 292 # Expected if the target was unable to install the 293 # fast tracepoint (e.g., jump pad too far from 294 # tracepoint). 295 pass "$test (too far)" 296 # Skip the rest of the tests. 297 return 298 } else { 299 fail $test 300 } 301 } 302 -re "Continuing.\r\n(Reading .* from remote target...\r\n)?\r\n(Thread .* hit )?Breakpoint.*marker.*at.*$srcfile.*$gdb_prompt $" { 303 pass $test 304 } 305 } 306 307 gdb_test "tstop" "\[\r\n\]+" "stop trace experiment" 308 309 # tracepoint should be resolved. 310 gdb_test "info trace" \ 311 "Num Type\[ \]+Disp Enb Address\[ \]+What.* 312\[0-9\]+\[\t \]+\(fast |\)tracepoint\[ \]+keep y.*pendfunc2.*" \ 313 "tracepoint is resolved" 314 315 # powerpc64 shows "in .pendfunc2" here. 316 gdb_test "tfind start" "#0 $hex in .?pendfunc2 .*" "tfind test frame 0" 317 gdb_test "tfind" "Target failed to find requested trace frame..*" "tfind test frame" 318}} 319 320 321# Verify pending tracepoint will no longer work if we disconnect during tracing. 322 323proc pending_tracepoint_disconnect_during_trace { trace_type } \ 324{ with_test_prefix "$trace_type disconn" \ 325{ 326 global executable 327 global srcfile 328 global lib_sl1 329 global gdb_prompt 330 331 # Start with a fresh gdb. 332 clean_restart $executable 333 if ![runto_main] { 334 fail "can't run to main" 335 return -1 336 } 337 338 gdb_test_multiple "trace pendfunc3" "set pending tracepoint on set_point2" { 339 -re ".*Make \(fast |\)tracepoint pending.*y or \\\[n\\\]. $" { 340 gdb_test "y" "\(Fast t|T\)racepoint.*pendfunc3.*pending." \ 341 "set pending tracepoint on pendfun3" 342 } 343 } 344 345 gdb_test "break marker" "Breakpoint.*at.* file .*$srcfile, line.*" \ 346 "breakpoint on marker" 347 348 gdb_test_no_output "tstart" "start trace experiment" 349 350 gdb_test "continue" "Continuing.\r\n\r\n(Thread .* hit )?Breakpoint.*marker.*at.*pending.c.*" \ 351 "continue to marker" 352 353 set test "disconnect with pending tracepoint" 354 gdb_test_multiple "disconnect" $test { 355 -re "warning: Pending tracepoints will not be resolved while GDB is disconnected.*Trace is running but will stop on detach; detach anyway\\? \\(y or n\\) $" { 356 pass $test 357 358 set test "disconnected" 359 gdb_test_multiple "y" $test { 360 -re "$gdb_prompt $" { 361 pass "$test" 362 } 363 } 364 } 365 } 366}} 367 368 369# Verify disconnect after pending tracepoint has been resolved. 370 371proc pending_tracepoint_disconnect_after_resolved { trace_type } \ 372{ with_test_prefix "$trace_type disconn_resolved" \ 373{ 374 global executable 375 global srcfile 376 global lib_sl1 377 global gdb_prompt 378 379 # Start with a fresh gdb. 380 clean_restart $executable 381 if ![runto_main] { 382 fail "can't run to main" 383 return -1 384 } 385 386 gdb_test_multiple "trace set_point2" "set pending tracepoint on set_point2" { 387 -re ".*Make \(fast |\)tracepoint pending.*y or \\\[n\\\]. $" { 388 gdb_test "y" "\(Fast t|T\)racepoint.*set_point2.*pending." \ 389 "set pending tracepoint on pendfun2" 390 } 391 } 392 393 gdb_test "break marker" "Breakpoint.*at.* file .*$srcfile, line.*" \ 394 "breakpoint on marker" 395 396 gdb_test_no_output "tstart" "start trace experiment" 397 398 gdb_test "continue" "Continuing.\r\n\r\n(Thread .* hit )?Breakpoint.*marker.*at.*pending.c.*" \ 399 "continue to marker 1" 400 gdb_test "continue" "Continuing.\r\n(Reading .* from remote target...\r\n)?\r\n(Thread .* hit )?Breakpoint.*marker.*at.*pending.c.*" \ 401 "continue to marker 2" 402 403 # There should be no pending tracepoint, so no warning should be emitted. 404 set test "disconnect with resolved tracepoint" 405 gdb_test_multiple "disconnect" $test { 406 -re "warning: Pending tracepoints will not be resolved while GDB is disconnected.*Trace is running but will stop on detach; detach anyway\\? \\(y or n\\) $" { 407 fail $test 408 } 409 -re "Trace is running but will stop on detach; detach anyway\\? \\(y or n\\) $" { 410 pass $test 411 } 412 } 413 set test "disconnected" 414 gdb_test_multiple "y" $test { 415 -re "$gdb_prompt $" { 416 pass "$test" 417 } 418 } 419}} 420 421# Verify action works properly in resolved tracepoint. 422 423proc pending_tracepoint_with_action_resolved { trace_type } \ 424{ with_test_prefix "$trace_type action_resolved" \ 425{ 426 global executable 427 global srcfile 428 global lib_sl1 429 global gdb_prompt 430 global pcreg 431 432 # Start with a fresh gdb. 433 clean_restart $executable 434 if ![runto_main] { 435 fail "can't run to main" 436 return -1 437 } 438 439 gdb_test_multiple "$trace_type set_point2" "set pending tracepoint on set_point2" { 440 -re ".*Make \(fast |\)tracepoint pending.*y or \\\[n\\\]. $" { 441 gdb_test "y" "\(Fast t|T\)racepoint.*set_point2.*pending." \ 442 "set pending tracepoint (without symbols)" 443 } 444 } 445 446 gdb_trace_setactions "set action for pending tracepoint" "" \ 447 "collect \$$pcreg" "^$" 448 449 gdb_test "info trace" \ 450 "Num Type\[ \]+Disp Enb Address\[ \]+What.* 451\[0-9\]+\[\t \]+\(fast |\)tracepoint\[ \]+keep y.*PENDING.*set_point2.*" \ 452 "single pending tracepoint on set_point2" 453 454 gdb_test "break marker" "Breakpoint.*at.* file .*$srcfile, line.*" \ 455 "breakpoint on marker" 456 457 gdb_test_no_output "tstart" "start trace experiment" 458 459 gdb_test "continue" "Continuing.\r\n\r\n(Thread .* hit )?Breakpoint.*marker.*at.*pending.c.*" \ 460 "continue to marker 1" 461 462 set test "continue to marker 2" 463 gdb_test_multiple "continue" $test { 464 -re "Target returns error code .* too far .*$gdb_prompt $" { 465 if [string equal $trace_type "ftrace"] { 466 # Expected if the target was unable to install the 467 # fast tracepoint (e.g., jump pad too far from 468 # tracepoint). 469 pass "$test (too far)" 470 # Skip the rest of the tests. 471 return 472 } else { 473 fail $test 474 } 475 } 476 -re "Continuing.\r\n(Reading .* from remote target...\r\n)?\r\n(Thread .* hit )?Breakpoint.*marker.*at.*$srcfile.*$gdb_prompt $" { 477 pass "continue to marker 2" 478 } 479 480 } 481 482 gdb_test "tstop" "\[\r\n\]+" "stop trace experiment" 483 484 # tracepoint should be resolved. 485 gdb_test "info trace" \ 486 "Num Type\[ \]+Disp Enb Address\[ \]+What.* 487\[0-9\]+\[\t \]+\(fast |\)tracepoint\[ \]+keep y.*pendfunc2.*" \ 488 "tracepoint is resolved" 489 490 gdb_test "tfind start" "#0 .*" "tfind test frame 0" 491 gdb_test "tdump" "Data collected at tracepoint .*, trace frame \[0-9\]:.*\\$${pcreg} = .*" 492 gdb_test "tfind" "Target failed to find requested trace frame..*" "tfind test frame" 493}} 494 495pending_tracepoint_resolved "trace" 496 497pending_tracepoint_works "trace" 498 499pending_tracepoint_resolved_during_trace "trace" 500 501pending_tracepoint_disconnect_during_trace "trace" 502 503pending_tracepoint_disconnect_after_resolved "trace" 504 505pending_tracepoint_with_action_resolved "trace" 506 507pending_tracepoint_installed_during_trace "trace" 508 509# Re-compile test case with IPA. 510set libipa [get_in_proc_agent] 511gdb_load_shlib $libipa 512 513lappend exec_opts "shlib=$libipa" 514 515if { [gdb_compile $srcdir/$subdir/$srcfile $binfile executable $exec_opts] != "" } { 516 untested "failed to compile with in-process agent library" 517 return -1 518} 519 520pending_tracepoint_resolved "ftrace" 521pending_tracepoint_works "ftrace" 522pending_tracepoint_resolved_during_trace "ftrace" 523pending_tracepoint_disconnect_during_trace "ftrace" 524pending_tracepoint_disconnect_after_resolved "ftrace" 525pending_tracepoint_with_action_resolved "ftrace" 526pending_tracepoint_installed_during_trace "ftrace" 527