1 # Copyright 2011-2024 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.
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.
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/>.
15 load_lib "trace-support.exp"
17 require allow_shlib_tests
19 require gdb_trace_common_supports_arch
22 set libfile1 "pendshr1"
23 set libfile2 "pendshr2"
24 set executable $testfile
25 set libsrc1 $srcdir/$subdir/$libfile1.c
26 set libsrc2 $srcdir/$subdir/$libfile2.c
27 set lib_sl1 [standard_output_file $libfile1.sl]
28 set lib_sl2 [standard_output_file $libfile2.sl]
30 set lib_opts [gdb_target_symbol_prefix_flags]
32 if { [gdb_compile_shlib $libsrc1 $lib_sl1 $lib_opts] != ""
33 || [gdb_compile_shlib $libsrc2 $lib_sl2 $lib_opts] != ""} {
34 untested "failed to compile shared library"
38 set exec_opts [list debug shlib=$lib_sl1 shlib_load]
39 if { [gdb_compile $srcdir/$subdir/$srcfile $binfile executable $exec_opts] != "" } {
40 untested "failed to compile"
44 clean_restart $executable
46 gdb_load_shlib $lib_sl1
47 gdb_load_shlib $lib_sl2
53 if ![gdb_target_supports_trace] {
54 unsupported "current target does not support trace"
58 # Verify pending tracepoint is resolved to running to main.
60 proc pending_tracepoint_resolved { trace_type } {
61 with_test_prefix "$trace_type resolved" {
68 # Start with a fresh gdb.
71 gdb_test_multiple "$trace_type set_point1" "set pending tracepoint" {
72 -re ".*Make \(fast |\)tracepoint pending.*y or \\\[n\\\]. $" {
73 gdb_test "y" "\(Fast t|T\)racepoint.*set_point1.*pending." \
74 "set pending tracepoint (without symbols)"
78 gdb_test "info trace" \
79 "Num Type\[ \]+Disp Enb Address\[ \]+What.*
80 \[0-9\]+\[\t \]+\(fast |\)tracepoint\[ \]+keep y.*PENDING.*set_point1.*" \
81 "single pending tracepoint info (without symbols)"
85 gdb_test "break -q main" "Breakpoint.*at.* file .*$srcfile, line.*" \
89 gdb_test "" "Breakpoint 2, main.*"
91 # Run to main which should resolve a pending tracepoint
92 gdb_test "info trace" \
93 "Num Type\[ \]+Disp Enb Address\[ \]+What.*
94 \[0-9\]+\[\t \]+\(fast |\)tracepoint\[ \]+keep y.*pendfunc.*" \
95 "single tracepoint info"
99 # Verify pending tracepoint is resolved and works as expected.
101 proc pending_tracepoint_works { trace_type } {
102 with_test_prefix "$trace_type works" {
108 # Restart with a fresh gdb.
109 clean_restart $executable
111 # Test setting and querying pending tracepoints
113 gdb_test_multiple "$trace_type set_point1" "set pending tracepoint" {
114 -re ".*Make \(fast |\)tracepoint pending.*y or \\\[n\\\]. $" {
116 "\(Fast t|T\)racepoint.*set_point1.*pending." \
117 "set pending tracepoint"
121 gdb_test "info trace" \
122 "Num Type\[ \]+Disp Enb Address\[ \]+What.*
123 \[0-9\]+\[\t \]+\(fast |\)tracepoint\[ \]+keep y.*PENDING.*set_point1.*" \
124 "single pending tracepoint info"
126 # Run to main which should resolve a pending tracepoint
127 gdb_test "break -q main" "Breakpoint.*at.* file .*$srcfile, line.*" \
128 "breakpoint function"
130 gdb_test "" "Breakpoint 2, main.*"
132 gdb_test "break marker" "Breakpoint.*at.* file .*$srcfile, line.*" \
133 "breakpoint on marker"
135 set test "start trace experiment"
136 gdb_test_multiple "tstart" $test {
137 -re "^tstart\r\n$gdb_prompt $" {
140 -re "Target returns error code .* too far .*$gdb_prompt $" {
141 if [string equal $trace_type "ftrace"] {
142 # The target was unable to install the fast tracepoint
143 # (e.g., jump pad too far from tracepoint).
144 pass "$test (too far)"
145 # Skip the rest of the tests.
154 gdb_test "continue" "Continuing.\r\n\r\n(Thread .* hit )?Breakpoint.*marker.*at.*$srcfile.*" \
157 gdb_test_no_output "tstop" "stop trace experiment"
159 gdb_test "tfind start" "#0 .*" "tfind test frame 0"
160 gdb_test "tfind" "Found trace frame 1, tracepoint 1.*" \
162 gdb_test "tfind" "Found trace frame 2, tracepoint 1.*" \
165 "Target failed to find requested trace frame..*" \
170 # Verify pending tracepoint is resolved during trace.
172 proc pending_tracepoint_resolved_during_trace { trace_type } \
173 { with_test_prefix "$trace_type resolved_in_trace" \
180 # Start with a fresh gdb.
181 clean_restart $executable
186 gdb_test_multiple "$trace_type set_point2" "set pending tracepoint on set_point2" {
187 -re ".*Make \(fast |\)tracepoint pending.*y or \\\[n\\\]. $" {
188 gdb_test "y" "\(Fast t|T\)racepoint.*set_point2.*pending." \
189 "set pending tracepoint (without symbols)"
193 gdb_test "info trace" \
194 "Num Type\[ \]+Disp Enb Address\[ \]+What.*
195 \[0-9\]+\[\t \]+\(fast |\)tracepoint\[ \]+keep y.*PENDING.*set_point2.*" \
196 "single pending tracepoint on set_point2"
198 gdb_test "break marker" "Breakpoint.*at.* file .*$srcfile, line.*" \
199 "breakpoint on marker"
201 gdb_test_no_output "tstart" "start trace experiment"
203 gdb_test "continue" "Continuing.\r\n\r\n(Thread .* hit )?Breakpoint.*marker.*at.*pending.c.*" \
204 "continue to marker 1"
206 set test "continue to marker 2"
207 gdb_test_multiple "continue" $test {
208 -re "Target returns error code .* too far .*$gdb_prompt $" {
209 if [string equal $trace_type "ftrace"] {
210 # Expected if the target was unable to install the
211 # fast tracepoint (e.g., jump pad too far from
213 pass "$test (too far)"
214 # Skip the rest of the tests.
220 -re "Continuing.\r\n(Reading .* from remote target...\r\n)?\r\n(Thread .* hit )?Breakpoint.*marker.*at.*$srcfile.*$gdb_prompt $" {
225 gdb_test_no_output "tstop" "stop trace experiment"
227 # tracepoint should be resolved.
228 gdb_test "info trace" \
229 "Num Type\[ \]+Disp Enb Address\[ \]+What.*
230 \[0-9\]+\[\t \]+\(fast |\)tracepoint\[ \]+keep y.*pendfunc2.*" \
231 "tracepoint is resolved"
233 gdb_test "tfind start" "#0 .*" "tfind test frame 0"
234 gdb_test "tfind" "Target failed to find requested trace frame..*" "tfind test frame"
237 # Verify pending tracepoint is resolved and installed during trace.
239 proc pending_tracepoint_installed_during_trace { trace_type } \
240 { with_test_prefix "$trace_type installed_in_trace" \
248 # Start with a fresh gdb.
249 clean_restart $executable
255 gdb_test "trace main" "Tracepoint \[0-9\] at .*" "set tracepoint on main"
257 gdb_test "break marker" "Breakpoint.*at.* file .*$srcfile, line.*" \
258 "breakpoint on marker"
260 gdb_test_no_output "tstart" "start trace experiment"
262 gdb_test "continue" "Continuing.\r\n\r\n(Thread .* hit )?Breakpoint.*marker.*at.*${srcfile}.*" \
263 "continue to marker 1"
265 # Set a pending tracepoint during a tracing experiment.
266 gdb_test_multiple "$trace_type set_point2" "set pending tracepoint on set_point2" {
267 -re ".*Make \(fast |\)tracepoint pending.*y or \\\[n\\\]. $" {
268 gdb_test "y" "\(Fast t|T\)racepoint.*set_point2.*pending." \
269 "set pending tracepoint"
273 gdb_test "info trace" \
274 "Num Type\[ \]+Disp Enb Address\[ \]+What.*
275 \[0-9\]+\[\t \]+\(fast |\)tracepoint\[ \t\]+keep y.*PENDING.*set_point2.*" \
276 "single pending tracepoint on set_point2"
278 set test "continue to marker 2"
279 gdb_test_multiple "continue" $test {
280 -re "Target returns error code .* too far .*$gdb_prompt $" {
281 if [string equal $trace_type "ftrace"] {
282 # Expected if the target was unable to install the
283 # fast tracepoint (e.g., jump pad too far from
285 pass "$test (too far)"
286 # Skip the rest of the tests.
292 -re "Continuing.\r\n(Reading .* from remote target...\r\n)?\r\n(Thread .* hit )?Breakpoint.*marker.*at.*$srcfile.*$gdb_prompt $" {
297 gdb_test_no_output "tstop" "stop trace experiment"
299 # tracepoint should be resolved.
300 gdb_test "info trace" \
301 "Num Type\[ \]+Disp Enb Address\[ \]+What.*
302 \[0-9\]+\[\t \]+\(fast |\)tracepoint\[ \]+keep y.*pendfunc2.*" \
303 "tracepoint is resolved"
305 # powerpc64 shows "in .pendfunc2" here.
306 gdb_test "tfind start" "#0 $hex in .?pendfunc2 .*" "tfind test frame 0"
307 gdb_test "tfind" "Target failed to find requested trace frame..*" "tfind test frame"
311 # Verify pending tracepoint will no longer work if we disconnect during tracing.
313 proc pending_tracepoint_disconnect_during_trace { trace_type } \
314 { with_test_prefix "$trace_type disconn" \
321 # Start with a fresh gdb.
322 clean_restart $executable
327 gdb_test_multiple "trace pendfunc3" "set pending tracepoint on set_point2" {
328 -re ".*Make \(fast |\)tracepoint pending.*y or \\\[n\\\]. $" {
329 gdb_test "y" "\(Fast t|T\)racepoint.*pendfunc3.*pending." \
330 "set pending tracepoint on pendfun3"
334 gdb_test "break marker" "Breakpoint.*at.* file .*$srcfile, line.*" \
335 "breakpoint on marker"
337 gdb_test_no_output "tstart" "start trace experiment"
339 gdb_test "continue" "Continuing.\r\n\r\n(Thread .* hit )?Breakpoint.*marker.*at.*pending.c.*" \
342 set test "disconnect with pending tracepoint"
343 gdb_test_multiple "disconnect" $test {
344 -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\\) $" {
347 set test "disconnected"
348 gdb_test_multiple "y" $test {
349 -re "$gdb_prompt $" {
358 # Verify disconnect after pending tracepoint has been resolved.
360 proc pending_tracepoint_disconnect_after_resolved { trace_type } \
361 { with_test_prefix "$trace_type disconn_resolved" \
368 # Start with a fresh gdb.
369 clean_restart $executable
374 gdb_test_multiple "trace set_point2" "set pending tracepoint on set_point2" {
375 -re ".*Make \(fast |\)tracepoint pending.*y or \\\[n\\\]. $" {
376 gdb_test "y" "\(Fast t|T\)racepoint.*set_point2.*pending." \
377 "set pending tracepoint on pendfun2"
381 gdb_test "break marker" "Breakpoint.*at.* file .*$srcfile, line.*" \
382 "breakpoint on marker"
384 gdb_test_no_output "tstart" "start trace experiment"
386 gdb_test "continue" "Continuing.\r\n\r\n(Thread .* hit )?Breakpoint.*marker.*at.*pending.c.*" \
387 "continue to marker 1"
388 gdb_test "continue" "Continuing.\r\n(Reading .* from remote target...\r\n)?\r\n(Thread .* hit )?Breakpoint.*marker.*at.*pending.c.*" \
389 "continue to marker 2"
391 # There should be no pending tracepoint, so no warning should be emitted.
392 set test "disconnect with resolved tracepoint"
393 gdb_test_multiple "disconnect" $test {
394 -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\\) $" {
397 -re "Trace is running but will stop on detach; detach anyway\\? \\(y or n\\) $" {
401 set test "disconnected"
402 gdb_test_multiple "y" $test {
403 -re "$gdb_prompt $" {
409 # Verify action works properly in resolved tracepoint.
411 proc pending_tracepoint_with_action_resolved { trace_type } \
412 { with_test_prefix "$trace_type action_resolved" \
420 # Start with a fresh gdb.
421 clean_restart $executable
426 gdb_test_multiple "$trace_type set_point2" "set pending tracepoint on set_point2" {
427 -re ".*Make \(fast |\)tracepoint pending.*y or \\\[n\\\]. $" {
428 gdb_test "y" "\(Fast t|T\)racepoint.*set_point2.*pending." \
429 "set pending tracepoint (without symbols)"
433 gdb_trace_setactions "set action for pending tracepoint" "" \
434 "collect \$$pcreg" "^$"
436 gdb_test "info trace" \
437 "Num Type\[ \]+Disp Enb Address\[ \]+What.*
438 \[0-9\]+\[\t \]+\(fast |\)tracepoint\[ \]+keep y.*PENDING.*set_point2.*" \
439 "single pending tracepoint on set_point2"
441 gdb_test "break marker" "Breakpoint.*at.* file .*$srcfile, line.*" \
442 "breakpoint on marker"
444 gdb_test_no_output "tstart" "start trace experiment"
446 gdb_test "continue" "Continuing.\r\n\r\n(Thread .* hit )?Breakpoint.*marker.*at.*pending.c.*" \
447 "continue to marker 1"
449 set test "continue to marker 2"
450 gdb_test_multiple "continue" $test {
451 -re "Target returns error code .* too far .*$gdb_prompt $" {
452 if [string equal $trace_type "ftrace"] {
453 # Expected if the target was unable to install the
454 # fast tracepoint (e.g., jump pad too far from
456 pass "$test (too far)"
457 # Skip the rest of the tests.
463 -re "Continuing.\r\n(Reading .* from remote target...\r\n)?\r\n(Thread .* hit )?Breakpoint.*marker.*at.*$srcfile.*$gdb_prompt $" {
464 pass "continue to marker 2"
469 gdb_test_no_output "tstop" "stop trace experiment"
471 # tracepoint should be resolved.
472 gdb_test "info trace" \
473 "Num Type\[ \]+Disp Enb Address\[ \]+What.*
474 \[0-9\]+\[\t \]+\(fast |\)tracepoint\[ \]+keep y.*pendfunc2.*" \
475 "tracepoint is resolved"
477 gdb_test "tfind start" "#0 .*" "tfind test frame 0"
478 gdb_test "tdump" "Data collected at tracepoint .*, trace frame \[0-9\]:.*\\$${pcreg} = .*"
479 gdb_test "tfind" "Target failed to find requested trace frame..*" "tfind test frame"
482 pending_tracepoint_resolved "trace"
484 pending_tracepoint_works "trace"
486 pending_tracepoint_resolved_during_trace "trace"
488 pending_tracepoint_disconnect_during_trace "trace"
490 pending_tracepoint_disconnect_after_resolved "trace"
492 pending_tracepoint_with_action_resolved "trace"
494 pending_tracepoint_installed_during_trace "trace"
496 # Re-compile test case with IPA.
497 set libipa [get_in_proc_agent]
498 gdb_load_shlib $libipa
500 lappend exec_opts "shlib=$libipa"
502 if { [gdb_compile $srcdir/$subdir/$srcfile $binfile executable $exec_opts] != "" } {
503 untested "failed to compile with in-process agent library"
507 pending_tracepoint_resolved "ftrace"
508 pending_tracepoint_works "ftrace"
509 pending_tracepoint_resolved_during_trace "ftrace"
510 pending_tracepoint_disconnect_during_trace "ftrace"
511 pending_tracepoint_disconnect_after_resolved "ftrace"
512 pending_tracepoint_with_action_resolved "ftrace"
513 pending_tracepoint_installed_during_trace "ftrace"