gdb/testsuite/
[external/binutils.git] / gdb / testsuite / gdb.trace / pending.exp
1 # Copyright 2011-2013 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
15 load_lib "trace-support.exp";
16
17 if {[skip_shlib_tests]} {
18     return 0
19 }
20
21 standard_testfile
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]
29
30 set lib_opts [gdb_target_symbol_prefix_flags]
31
32 if { [gdb_compile_shlib $libsrc1 $lib_sl1 $lib_opts] != ""
33      || [gdb_compile_shlib $libsrc2 $lib_sl2 $lib_opts] != ""} {
34     untested "Could not compile either $libsrc1 or $libsrc2"
35     return -1
36 }
37
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 $srcfile"
41     return -1
42 }
43
44 clean_restart $executable
45
46 gdb_load_shlibs $lib_sl1
47 gdb_load_shlibs $lib_sl2
48
49 if ![runto_main] {
50     fail "Can't run to main to check for trace support"
51     return -1
52 }
53
54 if ![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
61 proc 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
104 proc 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\nBreakpoint.*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
175 proc 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\nBreakpoint.*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\r\nBreakpoint.*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
243 proc 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\nBreakpoint.*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\r\nBreakpoint.*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     gdb_test "tfind start" "#0  $hex in pendfunc2 .*" "tfind test frame 0"
311     gdb_test "tfind" "Target failed to find requested trace frame..*" "tfind test frame"
312 }}
313
314
315 # Verify pending tracepoint will no longer work if we disconnect during tracing.
316
317 proc pending_tracepoint_disconnect_during_trace { trace_type } \
318 { with_test_prefix "$trace_type disconn" \
319 {
320     global executable
321     global srcfile
322     global lib_sl1
323     global gdb_prompt
324
325     # Start with a fresh gdb.
326     clean_restart $executable
327     if ![runto_main] {
328         fail "Can't run to main"
329         return -1
330     }
331
332     gdb_test_multiple "trace pendfunc3" "set pending tracepoint on set_point2" {
333         -re ".*Make \(fast |\)tracepoint pending.*y or \\\[n\\\]. $" {
334             gdb_test "y" "\(Fast t|T\)racepoint.*pendfunc3.*pending." \
335                 "set pending tracepoint on pendfun3"
336         }
337     }
338
339     gdb_test "break marker" "Breakpoint.*at.* file .*$srcfile, line.*" \
340         "breakpoint on marker"
341
342     gdb_test_no_output "tstart" "start trace experiment"
343
344     gdb_test "continue" "Continuing.\r\n\r\nBreakpoint.*marker.*at.*pending.c.*" \
345         "continue to marker"
346
347     set test "disconnect with pending tracepoint"
348     gdb_test_multiple "disconnect" $test {
349        -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\\) $" {
350            pass $test
351
352            set test "disconnected"
353            gdb_test_multiple "y" $test {
354                -re "$gdb_prompt $" {
355                    pass "$test"
356                }
357            }
358        }
359     }
360 }}
361
362
363 # Verify disconnect after pending tracepoint has been resolved.
364
365 proc pending_tracepoint_disconnect_after_resolved { trace_type } \
366 { with_test_prefix "$trace_type disconn_resolved" \
367 {
368     global executable
369     global srcfile
370     global lib_sl1
371     global gdb_prompt
372
373     # Start with a fresh gdb.
374     clean_restart $executable
375     if ![runto_main] {
376         fail "Can't run to main"
377         return -1
378     }
379
380     gdb_test_multiple "trace set_point2" "set pending tracepoint on set_point2" {
381         -re ".*Make \(fast |\)tracepoint pending.*y or \\\[n\\\]. $" {
382             gdb_test "y" "\(Fast t|T\)racepoint.*set_point2.*pending." \
383                 "set pending tracepoint on pendfun2"
384         }
385     }
386
387     gdb_test "break marker" "Breakpoint.*at.* file .*$srcfile, line.*" \
388         "breakpoint on marker"
389
390     gdb_test_no_output "tstart" "start trace experiment"
391
392     gdb_test "continue" "Continuing.\r\n\r\nBreakpoint.*marker.*at.*pending.c.*" \
393         "continue to marker 1"
394     gdb_test "continue" "Continuing.\r\n\r\nBreakpoint.*marker.*at.*pending.c.*" \
395         "continue to marker 2"
396
397     # There should be no pending tracepoint, so no warning should be emitted.
398     set test "disconnect with resolved tracepoint"
399     gdb_test_multiple "disconnect" $test {
400         -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\\) $" {
401             fail $test
402         }
403         -re "Trace is running but will stop on detach; detach anyway\\? \\(y or n\\) $" {
404             pass $test
405         }
406     }
407     set test "disconnected"
408     gdb_test_multiple "y" $test {
409         -re "$gdb_prompt $" {
410             pass "$test"
411         }
412     }
413 }}
414
415 # Verify action works properly in resolved tracepoint.
416
417 proc pending_tracepoint_with_action_resolved { trace_type } \
418 { with_test_prefix "$trace_type action_resolved" \
419 {
420     global executable
421     global srcfile
422     global lib_sl1
423     global gdb_prompt
424
425     # Start with a fresh gdb.
426     clean_restart $executable
427     if ![runto_main] {
428         fail "Can't run to main"
429         return -1
430     }
431
432     gdb_test_multiple "$trace_type set_point2" "set pending tracepoint on set_point2" {
433         -re ".*Make \(fast |\)tracepoint pending.*y or \\\[n\\\]. $" {
434             gdb_test "y" "\(Fast t|T\)racepoint.*set_point2.*pending." \
435                 "set pending tracepoint (without symbols)"
436         }
437     }
438
439     set pcreg "pc"
440     if [is_amd64_regs_target] {
441         set pcreg "rip"
442     } elseif [is_x86_like_target] {
443         set pcreg "eip"
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\nBreakpoint.*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\r\nBreakpoint.*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
495 pending_tracepoint_resolved "trace"
496
497 pending_tracepoint_works "trace"
498
499 pending_tracepoint_resolved_during_trace "trace"
500
501 pending_tracepoint_disconnect_during_trace "trace"
502
503 pending_tracepoint_disconnect_after_resolved "trace"
504
505 pending_tracepoint_with_action_resolved "trace"
506
507 pending_tracepoint_installed_during_trace "trace"
508
509 # Re-compile test case with IPA.
510 set libipa [get_in_proc_agent]
511 gdb_load_shlibs $libipa
512
513 lappend exec_opts "shlib=$libipa"
514
515 if { [gdb_compile $srcdir/$subdir/$srcfile $binfile executable $exec_opts] != "" } {
516     untested "Failed to compile $srcfile"
517     return -1
518 }
519
520 pending_tracepoint_resolved "ftrace"
521 pending_tracepoint_works "ftrace"
522 pending_tracepoint_resolved_during_trace "ftrace"
523 pending_tracepoint_disconnect_during_trace "ftrace"
524 pending_tracepoint_disconnect_after_resolved "ftrace"
525 pending_tracepoint_with_action_resolved "ftrace"
526 pending_tracepoint_installed_during_trace "ftrace"