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