Automatic date update in version.in
[binutils-gdb.git] / gdb / testsuite / gdb.trace / report.exp
blob7146599277887e86bae38401d8baee3fb775bb9b
1 #   Copyright 1998-2024 Free Software Foundation, Inc.
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 3 of the License, or
6 # (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 # This file was written by Michael Snyder (msnyder@cygnus.com)
18 load_lib "trace-support.exp"
20 standard_testfile actions.c
21 require gdb_trace_common_supports_arch
22 if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \
23           executable {debug nowarnings nopie}] != "" } {
24     untested "failed to compile"
25     return -1
27 clean_restart $binfile
28 runto_main
30 if {![gdb_target_supports_trace]} {
31     unsupported "current target does not support trace"
32     return 1
36 set cr "\[\r\n\]+"
38 # If testing on a remote host, download the source file.
39 # remote_download host $srcdir/$subdir/$srcfile
42 # test general reporting of trace experiment results
45 set testline1 0
46 set testline2 0
47 set testline3 0
48 set testline4 0
49 set testline5 0
50 set testline6 0
52 set arg1 1
53 set arg2 2
54 set arg3 3
55 set arg4 4
56 set arg5 5
57 set arg6 6
59 set gdb_recursion_test_baseline [gdb_find_recursion_test_baseline $srcfile]
60 if { $gdb_recursion_test_baseline == -1 } {
61     fail "could not find gdb_recursion_test function"
62     return
65 set return_me 0
67 gdb_test_multiple "list $gdb_recursion_test_baseline, +12" "" {
68     -re "\[\r\n\](\[0-9\]+)\[^\r\n\]+gdbtestline 1 " {
69         set testline1 $expect_out(1,string)
70         exp_continue
71     }
72     -re "\[\r\n\](\[0-9\]+)\[^\r\n\]+gdbtestline 2 " {
73         set testline2 $expect_out(1,string)
74         exp_continue
75     }
76     -re "\[\r\n\](\[0-9\]+)\[^\r\n\]+gdbtestline 3 " {
77         set testline3 $expect_out(1,string)
78         exp_continue
79     }
80     -re "\[\r\n\](\[0-9\]+)\[^\r\n\]+gdbtestline 4 " {
81         set testline4 $expect_out(1,string)
82         exp_continue
83     }
84     -re "\[\r\n\](\[0-9\]+)\[^\r\n\]+gdbtestline 5 " {
85         set testline5 $expect_out(1,string)
86         exp_continue
87     }
88     -re "\[\r\n\](\[0-9\]+)\[^\r\n\]+gdbtestline 6 " {
89         set testline6 $expect_out(1,string)
90         exp_continue
91     }
92     -re ".*$gdb_prompt $" {
93         if { ($testline1 == 0) || ($testline2 == 0) || ($testline3 == 0) || ($testline4 == 0) || ($testline5 == 0) || ($testline6 == 0) } {
94             untested "unexpected testline values"
95             set return_me 1
96 all tests in this module will fail."
97         }
98     }
99     default {
100             untested "couldn't match pattern"
101             set return_me 1
102 all tests in this module will fail."
103     } 
106 if {$return_me == 1} {
107     return -1
111 # Setup trace experiment.  This will involve:
112 #   1) a tracepoint where nothing is collected
113 #   2) a tracepoint where only regs are collected
114 #   3) a tracepoint where only args are collected
115 #   4) a tracepoint where only locals are collected
116 #   5) a tracepoint where some amount of stack memory is collected.
117 #   6) a tracepoint where some expressions are collected.
120 gdb_delete_tracepoints
121 set tdp1 [gdb_gettpnum $testline1]
122 set tdp2 [gdb_gettpnum $testline2]
123 set tdp3 [gdb_gettpnum $testline3]
124 set tdp4 [gdb_gettpnum $testline4]
125 set tdp5 [gdb_gettpnum $testline5]
126 set tdp6 [gdb_gettpnum $testline6]
128 if {    $tdp1 <= 0 || $tdp2 <= 0 || $tdp3 <= 0 || \
129         $tdp4 <= 0 || $tdp5 <= 0 || $tdp6 <= 0 } then {
130     fail "setting tracepoints failed"
131     return
134 gdb_trace_setactions "9.x: setup TP to collect regs" \
135         "$tdp2" \
136         "collect \$regs" "^$"
139 gdb_trace_setactions "9.x: setup TP to collect args" \
140         "$tdp3" \
141         "collect \$args" "^$"
143 gdb_trace_setactions "9.x: setup TP to collect locals" \
144         "$tdp4" \
145         "collect \$locs" "^$"
147 gdb_trace_setactions "9.x: setup TP to collect stack memory" \
148         "$tdp5" \
149         "collect \$$fpreg, \*\(void \*\*\) \$$spreg @ 64" "^$"
151 gdb_trace_setactions "9.x: setup TP to collect expressions" \
152         "$tdp6" \
153         "collect gdb_char_test, gdb_short_test, gdb_long_test" "^$"
155 gdb_test "tstart" ".*" ""
157 gdb_breakpoint "end" qualified
158 gdb_test "continue" \
159     "Continuing.*Breakpoint $decimal, end.*" \
160     "run trace experiment"
162 gdb_test "tstop" ".*" ""
164 gdb_tfind_test "9.1: init: make sure not debugging any trace frame" \
165     "none" "-1"
167 # 9.3 help tdump
169 gdb_test "help tdump" "Print everything collected at the current.*" \
170         "9.3: help tdump"
172 # Check the collected trace data from different sources, such as live
173 # inferior and tfile.
175 proc use_collected_data { data_source } {
176     global tdlabel_re
178     with_test_prefix "${data_source}" {
179         global tdp1 tdp2 tdp3 tdp4 tdp5 tdp6
180         global testline1 testline2 testline3 testline4 testline5 testline6
181         global pcreg fpreg spreg
182         global srcfile srcdir subdir binfile
183         global arg1 arg3
184         global decimal hex gdb_prompt
185         #
186         # 9.1 test the tdump command
187         #
189         set timeout 60
191         gdb_tfind_test "9.1: find frame for TP $tdp1" "tracepoint $tdp1" \
192             "\$tracepoint" "$tdp1"
194         # Nothing was collected at tdp1, so this tdump should be empty.
195         gdb_test "tdump" \
196             "Data collected at tracepoint $tdp1, trace frame $decimal:" \
197             "9.1: tdump, nothing collected"
199         gdb_tfind_test "9.1: find frame for TP $tdp2" "tracepoint $tdp2" \
200             "\$tracepoint" "$tdp2"
202         # regs were collected at tdp2.
203         # How to match for the output of "info registers" on an unknown architecture?
204         # For now, assume that most architectures have a register called "pc".
206         gdb_test "tdump" \
207             "\[\r\n\]$pcreg .*" \
208             "9.1: tdump, regs collected"
210         gdb_tfind_test "9.1: find frame for TP $tdp3" "tracepoint $tdp3" \
211             "\$tracepoint" "$tdp3"
213         # args were collected at tdp3
214         gdb_test "tdump" \
215             "depth = 3.*q1 = 2.*q2 = 2.*q3 = 3.*q4 = 4.*q5 = 5.*q6 = 6" \
216             "9.1: tdump, args collected"
218         gdb_tfind_test "9.1: find frame for TP $tdp4" "tracepoint $tdp4" \
219             "\$tracepoint" "$tdp4"
221         # locals were collected at tdp4
222         gdb_test "tdump" \
223             "q = 1" \
224             "9.1: tdump, locals collected"
226         gdb_tfind_test "9.1: find frame for TP $tdp5" "tracepoint $tdp5" \
227             "\$tracepoint" "$tdp5"
229         # stack was collected at tdp5, plus the frame pointer
230         gdb_test "tdump" \
231             ".$fpreg = .*$spreg @ 64 = .*" \
232             "9.1: tdump, memrange collected"
234         gdb_tfind_test "9.1: find frame for TP $tdp6" "tracepoint $tdp6" \
235             "\$tracepoint" "$tdp6"
237         # globals were collected at tdp6
238         gdb_test "tdump" \
239             "gdb_char_test = 1.*gdb_short_test = 2.*gdb_long_test = 3" \
240             "9.1: tdump, global variables collected"
242         # 9.2 test tdump with arguments
243         #     [no go, tdump doesn't have any arguments]
245         set linecount1 0
246         set linecount2 0
247         set linecount3 0
248         set linecount4 0
249         set linecount5 0
250         set linecount6 0
252         gdb_tfind_test "11.x, 12.1: find start frame" "start" "0"
254         #
255         # 11.x test built-in trace variables $trace_frame, $trace_line etc.
256         #
258         gdb_test "printf \"x %d x\\n\", \$trace_frame" "x 0 x" \
259             "11.1: test \$trace_frame"
261         gdb_test "printf \"x %d x\\n\", \$tracepoint" "x $tdp1 x" \
262             "11.2: test \$tracepoint"
264         gdb_test "printf \"x %d x\\n\", \$trace_line" "x $testline1 x" \
265             "11.3: test \$trace_line"
267         gdb_test_multiple "print \$trace_file" "11.4: test \$trace_file" {
268             -re "\\$\[0-9\]+ = \"$srcfile\"\[\r\n\]+$gdb_prompt $" {
269                 pass "11.4: test \$trace_file"
270             }
271             -re "\\$\[0-9\]+ = \"$srcdir/$subdir/$srcfile\"\[\r\n\]+$gdb_prompt $" {
272                 pass "11.4: test \$trace_file"
273             }
274         }
276         #gdb_test "print \$trace_file" "\"$srcdir/$subdir/$srcfile\"" \
277             #   "11.4: test \$trace_file"
279         #
280         # 12.x test report generation using arbitrary GDB commands, loops etc.
281         #
283         gdb_test_multiple "while \$trace_frame != -1\n  output \$trace_file\n  printf \", line \%d \(tracepoint #\%d\)\\n\", \$trace_line, \$tracepoint\n  tfind\n  end" "12.1: trace report #1" {
284             -re ">  end\r\n" {
285                 exp_continue
286             }
287             -re "^Found trace frame \[0-9\]+, tracepoint \[0-9\]+\r\n" {
288                 exp_continue
289             }
290             -re "^\[^\r\n\]* line $testline1 .tracepoint .$tdp1\\)\r\n" {
291                 set linecount1 [expr $linecount1 + 1]
292                 exp_continue
293             }
294             -re "^\[^\r\n\]* line $testline2 .tracepoint .$tdp2\\)\r\n" {
295                 set linecount2 [expr $linecount2 + 1]
296                 exp_continue
297             }
298             -re "^\[^\r\n\]* line $testline3 .tracepoint .$tdp3\\)\r\n" {
299                 set linecount3 [expr $linecount3 + 1]
300                 exp_continue
301             }
302             -re "^\[^\r\n\]* line $testline4 .tracepoint .$tdp4\\)\r\n" {
303                 set linecount4 [expr $linecount4 + 1]
304                 exp_continue
305             }
306             -re "^\[^\r\n\]* line $testline5 .tracepoint .$tdp5\\)\r\n" {
307                 set linecount5 [expr $linecount5 + 1]
308                 exp_continue
309             }
310             -re "^\[^\r\n\]* line $testline6 .tracepoint .$tdp6\\)\r\n" {
311                 set linecount6 [expr $linecount6 + 1]
312                 exp_continue
313             }
314             -re "^No trace frame found\r\n$gdb_prompt $" {
315                 if { ($linecount1 < 4) || ($linecount2 < 4) || ($linecount3 < 4) || ($linecount4 < 4) || ($linecount5 < 4) || ($linecount6 < 4) } {
316                     fail "12.1: trace report #1"
317                 } else {
318                     pass "12.1: trace report #1"
319                 }
320             }
321         }
323         gdb_tfind_test "12.2: tfind end, selects no frame" "end" "-1"
324         gdb_tfind_test "12.2: find first TDP #2 frame" "tracepoint $tdp2" \
325             "\$tracepoint" "$tdp2"
327         set linecount2 0
329         gdb_test_multiple "while \$trace_frame != -1\n printf \"tracepoint #\%d, FP 0x\%08x, SP 0x\%08x, PC 0x%08x\\n\", \$tracepoint, \$fp, \$sp, \$pc\n tfind tracepoint\n end" "12.2: trace report #2" {
330             -re "tracepoint #$tdp2, FP $hex, SP $hex, PC $hex" {
331                 set linecount2 [expr $linecount2 + 1]
332                 exp_continue
333             }
334             -re ".*$gdb_prompt $" {
335                 if { ($linecount2 < 4) } {
336                     fail "12.2: trace report #2"
337                 } else {
338                     pass "12.2: trace report #2"
339                 }
340             }
341         }
343         gdb_tfind_test "12.3: tfind end, selects no frame" "end" "-1"
344         gdb_tfind_test "12.3: find first TDP #3 frame" "tracepoint $tdp3" \
345             "\$tracepoint" "$tdp3"
347         set linecount3 0
349         gdb_test_multiple "while \$trace_frame != -1\n printf \"TDP #\%d, frame \%d: depth = \%d, q1 = \%d\\n\", \$tracepoint, \$trace_frame, depth, q1\n tfind tracepoint\n end" "12.3: trace report #3" {
350             -re "TDP #$tdp3, frame $decimal: depth = $decimal, q1 = $decimal" {
351                 set linecount3 [expr $linecount3 + 1]
352                 exp_continue
353             }
354             -re ".*$gdb_prompt $" {
355                 if { ($linecount3 < 4) } {
356                     fail "12.3: trace report #3"
357                 } else {
358                     pass "12.3: trace report #3"
359                 }
360             }
361         }
363         gdb_tfind_test "12.4: tfind end, selects no frame" "end" "-1"
364         gdb_tfind_test "12.4: find first TDP #6 frame" "tracepoint $tdp6" \
365             "\$tracepoint" "$tdp6"
367         set linecount6 0
369         gdb_test_multiple "while \$trace_frame != -1\n printf \"TDP #\%d, frame %d: char_test = \%d, long_test = \%d\\n\", \$tracepoint, \$trace_frame, gdb_char_test, gdb_long_test\n tfind tracepoint\n end" "12.4: trace report #4" {
370             -re "TDP #$tdp6, frame $decimal: char_test = $arg1, long_test = $arg3" {
371                 set linecount6 [expr $linecount6 + 1]
372                 exp_continue
373             }
374             -re ".*$gdb_prompt $" {
375                 if { ($linecount6 < 4) } {
376                     fail "12.4: trace report #4"
377                 } else {
378                     pass "12.4: trace report #4"
379                 }
380             }
381         }
383         # There is always a thread of an inferior, either a live one or
384         # a faked one.
385         gdb_test "info threads" "\\* ${decimal}    ${tdlabel_re} \[0-9\.\]+\[ \t\].*"
386         gdb_test "info inferiors" "\\* 1    process ${decimal} \[ \t\]+\[^\r\n\]*\[ \t\]+${binfile}.*"
387     }
390 use_collected_data "live"
392 # Finished!
393 gdb_tfind_test "finished: make sure not debugging any trace frame" \
394     "none" "-1"
396 # Save trace frames to tfile.
397 set tracefile [standard_output_file ${testfile}]
398 gdb_test "tsave ${tracefile}.tf" \
399     "Trace data saved to file '${tracefile}.tf'.*" \
400     "save tfile trace file"
402 # Save trace frames to ctf.
403 gdb_test "tsave -ctf ${tracefile}.ctf" \
404     "Trace data saved to directory '${tracefile}.ctf'.*" \
405     "save ctf trace file"
407 # Change target to tfile.
408 set test "change to tfile target"
409 gdb_test_multiple "target tfile ${tracefile}.tf" "$test" {
410     -re "A program is being debugged already.  Kill it. .y or n. " {
411         send_gdb "y\n"
412         exp_continue
413     }
414     -re "$gdb_prompt $" {
415         pass "$test"
416     }
418 # Test the collected trace frames from tfile.
419 use_collected_data "tfile"
421 # Try to read ctf data if GDB supports.
422 gdb_test_multiple "target ctf ${tracefile}.ctf" "" {
423     -re "Undefined target command: \"ctf ${tracefile}.ctf\"\.  Try \"help target\"\.\r\n$gdb_prompt $" {
424     }
425     -re ".*\r\n$gdb_prompt $" {
426         use_collected_data "ctf"
427     }