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