xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/testsuite/gdb.trace/report.exp (revision 32d1c65c71fbdb65a012e8392a62a757dd6853e9)
1#   Copyright 1998-2023 Free Software Foundation, Inc.
2#
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.
7#
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.
12#
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/>.
15
16# This file was written by Michael Snyder (msnyder@cygnus.com)
17
18load_lib "trace-support.exp"
19
20
21gdb_exit
22gdb_start
23
24standard_testfile actions.c
25if ![gdb_trace_common_supports_arch] {
26    unsupported "no trace-common.h support for arch"
27    return -1
28}
29if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \
30	  executable {debug nowarnings nopie}] != "" } {
31    untested "failed to compile"
32    return -1
33}
34gdb_load $binfile
35runto_main
36gdb_reinitialize_dir $srcdir/$subdir
37
38if {![gdb_target_supports_trace]} {
39    unsupported "current target does not support trace"
40    return 1
41
42}
43
44set cr "\[\r\n\]+"
45
46# If testing on a remote host, download the source file.
47# remote_download host $srcdir/$subdir/$srcfile
48
49#
50# test general reporting of trace experiment results
51#
52
53set testline1 0
54set testline2 0
55set testline3 0
56set testline4 0
57set testline5 0
58set testline6 0
59
60set arg1 1
61set arg2 2
62set arg3 3
63set arg4 4
64set arg5 5
65set arg6 6
66
67set gdb_recursion_test_baseline [gdb_find_recursion_test_baseline $srcfile]
68if { $gdb_recursion_test_baseline == -1 } {
69    fail "could not find gdb_recursion_test function"
70    return
71}
72
73set return_me 0
74
75gdb_test_multiple "list $gdb_recursion_test_baseline, +12" "" {
76    -re "\[\r\n\](\[0-9\]+)\[^\r\n\]+gdbtestline 1 " {
77	set testline1 $expect_out(1,string)
78	exp_continue
79    }
80    -re "\[\r\n\](\[0-9\]+)\[^\r\n\]+gdbtestline 2 " {
81	set testline2 $expect_out(1,string)
82	exp_continue
83    }
84    -re "\[\r\n\](\[0-9\]+)\[^\r\n\]+gdbtestline 3 " {
85	set testline3 $expect_out(1,string)
86	exp_continue
87    }
88    -re "\[\r\n\](\[0-9\]+)\[^\r\n\]+gdbtestline 4 " {
89	set testline4 $expect_out(1,string)
90	exp_continue
91    }
92    -re "\[\r\n\](\[0-9\]+)\[^\r\n\]+gdbtestline 5 " {
93	set testline5 $expect_out(1,string)
94	exp_continue
95    }
96    -re "\[\r\n\](\[0-9\]+)\[^\r\n\]+gdbtestline 6 " {
97	set testline6 $expect_out(1,string)
98	exp_continue
99    }
100    -re ".*$gdb_prompt $" {
101	if { ($testline1 == 0) || ($testline2 == 0) || ($testline3 == 0) || ($testline4 == 0) || ($testline5 == 0) || ($testline6 == 0) } {
102	    untested "unexpected testline values"
103	    set return_me 1
104all tests in this module will fail."
105	}
106    }
107    default {
108	    untested "couldn't match pattern"
109	    set return_me 1
110all tests in this module will fail."
111    }
112}
113
114if {$return_me == 1} {
115    return -1
116}
117
118#
119# Setup trace experiment.  This will involve:
120#   1) a tracepoint where nothing is collected
121#   2) a tracepoint where only regs are collected
122#   3) a tracepoint where only args are collected
123#   4) a tracepoint where only locals are collected
124#   5) a tracepoint where some amount of stack memory is collected.
125#   6) a tracepoint where some expressions are collected.
126#
127
128gdb_delete_tracepoints
129set tdp1 [gdb_gettpnum $testline1]
130set tdp2 [gdb_gettpnum $testline2]
131set tdp3 [gdb_gettpnum $testline3]
132set tdp4 [gdb_gettpnum $testline4]
133set tdp5 [gdb_gettpnum $testline5]
134set tdp6 [gdb_gettpnum $testline6]
135
136if {    $tdp1 <= 0 || $tdp2 <= 0 || $tdp3 <= 0 || \
137	$tdp4 <= 0 || $tdp5 <= 0 || $tdp6 <= 0 } then {
138    fail "setting tracepoints failed"
139    return
140}
141
142gdb_trace_setactions "9.x: setup TP to collect regs" \
143	"$tdp2" \
144	"collect \$regs" "^$"
145
146
147gdb_trace_setactions "9.x: setup TP to collect args" \
148	"$tdp3" \
149	"collect \$args" "^$"
150
151gdb_trace_setactions "9.x: setup TP to collect locals" \
152	"$tdp4" \
153	"collect \$locs" "^$"
154
155gdb_trace_setactions "9.x: setup TP to collect stack memory" \
156	"$tdp5" \
157	"collect \$$fpreg, \*\(void \*\*\) \$$spreg @ 64" "^$"
158
159gdb_trace_setactions "9.x: setup TP to collect expressions" \
160	"$tdp6" \
161	"collect gdb_char_test, gdb_short_test, gdb_long_test" "^$"
162
163gdb_test "tstart" ".*" ""
164
165gdb_breakpoint "end" qualified
166gdb_test "continue" \
167    "Continuing.*Breakpoint $decimal, end.*" \
168    "run trace experiment"
169
170gdb_test "tstop" ".*" ""
171
172gdb_tfind_test "9.1: init: make sure not debugging any trace frame" \
173    "none" "-1"
174
175# 9.3 help tdump
176
177gdb_test "help tdump" "Print everything collected at the current.*" \
178	"9.3: help tdump"
179
180# Check the collected trace data from different sources, such as live
181# inferior and tfile.
182
183proc use_collected_data { data_source } {
184    with_test_prefix "${data_source}" {
185	global tdp1 tdp2 tdp3 tdp4 tdp5 tdp6
186	global testline1 testline2 testline3 testline4 testline5 testline6
187	global pcreg fpreg spreg
188	global srcfile srcdir subdir binfile
189	global arg1 arg3
190	global decimal hex gdb_prompt
191	#
192	# 9.1 test the tdump command
193	#
194
195	set timeout 60
196
197	gdb_tfind_test "9.1: find frame for TP $tdp1" "tracepoint $tdp1" \
198	    "\$tracepoint" "$tdp1"
199
200	# Nothing was collected at tdp1, so this tdump should be empty.
201	gdb_test "tdump" \
202	    "Data collected at tracepoint $tdp1, trace frame $decimal:" \
203	    "9.1: tdump, nothing collected"
204
205	gdb_tfind_test "9.1: find frame for TP $tdp2" "tracepoint $tdp2" \
206	    "\$tracepoint" "$tdp2"
207
208	# regs were collected at tdp2.
209	# How to match for the output of "info registers" on an unknown architecture?
210	# For now, assume that most architectures have a register called "pc".
211
212	gdb_test "tdump" \
213	    "\[\r\n\]$pcreg .*" \
214	    "9.1: tdump, regs collected"
215
216	gdb_tfind_test "9.1: find frame for TP $tdp3" "tracepoint $tdp3" \
217	    "\$tracepoint" "$tdp3"
218
219	# args were collected at tdp3
220	gdb_test "tdump" \
221	    "depth = 3.*q1 = 2.*q2 = 2.*q3 = 3.*q4 = 4.*q5 = 5.*q6 = 6" \
222	    "9.1: tdump, args collected"
223
224	gdb_tfind_test "9.1: find frame for TP $tdp4" "tracepoint $tdp4" \
225	    "\$tracepoint" "$tdp4"
226
227	# locals were collected at tdp4
228	gdb_test "tdump" \
229	    "q = 1" \
230	    "9.1: tdump, locals collected"
231
232	gdb_tfind_test "9.1: find frame for TP $tdp5" "tracepoint $tdp5" \
233	    "\$tracepoint" "$tdp5"
234
235	# stack was collected at tdp5, plus the frame pointer
236	gdb_test "tdump" \
237	    ".$fpreg = .*$spreg @ 64 = .*" \
238	    "9.1: tdump, memrange collected"
239
240	gdb_tfind_test "9.1: find frame for TP $tdp6" "tracepoint $tdp6" \
241	    "\$tracepoint" "$tdp6"
242
243	# globals were collected at tdp6
244	gdb_test "tdump" \
245	    "gdb_char_test = 1.*gdb_short_test = 2.*gdb_long_test = 3" \
246	    "9.1: tdump, global variables collected"
247
248	# 9.2 test tdump with arguments
249	#     [no go, tdump doesn't have any arguments]
250
251	set linecount1 0
252	set linecount2 0
253	set linecount3 0
254	set linecount4 0
255	set linecount5 0
256	set linecount6 0
257
258	gdb_tfind_test "11.x, 12.1: find start frame" "start" "0"
259
260	#
261	# 11.x test built-in trace variables $trace_frame, $trace_line etc.
262	#
263
264	gdb_test "printf \"x %d x\\n\", \$trace_frame" "x 0 x" \
265	    "11.1: test \$trace_frame"
266
267	gdb_test "printf \"x %d x\\n\", \$tracepoint" "x $tdp1 x" \
268	    "11.2: test \$tracepoint"
269
270	gdb_test "printf \"x %d x\\n\", \$trace_line" "x $testline1 x" \
271	    "11.3: test \$trace_line"
272
273	gdb_test_multiple "print \$trace_file" "11.4: test \$trace_file" {
274	    -re "\\$\[0-9\]+ = \"$srcfile\"\[\r\n\]+$gdb_prompt $" {
275		pass "11.4: test \$trace_file"
276	    }
277	    -re "\\$\[0-9\]+ = \"$srcdir/$subdir/$srcfile\"\[\r\n\]+$gdb_prompt $" {
278		pass "11.4: test \$trace_file"
279	    }
280	}
281
282	#gdb_test "print \$trace_file" "\"$srcdir/$subdir/$srcfile\"" \
283	    #	"11.4: test \$trace_file"
284
285	#
286	# 12.x test report generation using arbitrary GDB commands, loops etc.
287	#
288
289	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" {
290	    -re ">  end\r\n" {
291		exp_continue
292	    }
293	    -re "^Found trace frame \[0-9\]+, tracepoint \[0-9\]+\r\n" {
294		exp_continue
295	    }
296	    -re "^\[^\r\n\]* line $testline1 .tracepoint .$tdp1\\)\r\n" {
297		set linecount1 [expr $linecount1 + 1]
298		exp_continue
299	    }
300	    -re "^\[^\r\n\]* line $testline2 .tracepoint .$tdp2\\)\r\n" {
301		set linecount2 [expr $linecount2 + 1]
302		exp_continue
303	    }
304	    -re "^\[^\r\n\]* line $testline3 .tracepoint .$tdp3\\)\r\n" {
305		set linecount3 [expr $linecount3 + 1]
306		exp_continue
307	    }
308	    -re "^\[^\r\n\]* line $testline4 .tracepoint .$tdp4\\)\r\n" {
309		set linecount4 [expr $linecount4 + 1]
310		exp_continue
311	    }
312	    -re "^\[^\r\n\]* line $testline5 .tracepoint .$tdp5\\)\r\n" {
313		set linecount5 [expr $linecount5 + 1]
314		exp_continue
315	    }
316	    -re "^\[^\r\n\]* line $testline6 .tracepoint .$tdp6\\)\r\n" {
317		set linecount6 [expr $linecount6 + 1]
318		exp_continue
319	    }
320	    -re "^No trace frame found\r\n$gdb_prompt $" {
321		if { ($linecount1 < 4) || ($linecount2 < 4) || ($linecount3 < 4) || ($linecount4 < 4) || ($linecount5 < 4) || ($linecount6 < 4) } {
322		    fail "12.1: trace report #1"
323		} else {
324		    pass "12.1: trace report #1"
325		}
326	    }
327	}
328
329	gdb_tfind_test "12.2: tfind end, selects no frame" "end" "-1"
330	gdb_tfind_test "12.2: find first TDP #2 frame" "tracepoint $tdp2" \
331	    "\$tracepoint" "$tdp2"
332
333	set linecount2 0
334
335	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" {
336	    -re "tracepoint #$tdp2, FP $hex, SP $hex, PC $hex" {
337		set linecount2 [expr $linecount2 + 1]
338		exp_continue
339	    }
340	    -re ".*$gdb_prompt $" {
341		if { ($linecount2 < 4) } {
342		    fail "12.2: trace report #2"
343		} else {
344		    pass "12.2: trace report #2"
345		}
346	    }
347	}
348
349	gdb_tfind_test "12.3: tfind end, selects no frame" "end" "-1"
350	gdb_tfind_test "12.3: find first TDP #3 frame" "tracepoint $tdp3" \
351	    "\$tracepoint" "$tdp3"
352
353	set linecount3 0
354
355	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" {
356	    -re "TDP #$tdp3, frame $decimal: depth = $decimal, q1 = $decimal" {
357		set linecount3 [expr $linecount3 + 1]
358		exp_continue
359	    }
360	    -re ".*$gdb_prompt $" {
361		if { ($linecount3 < 4) } {
362		    fail "12.3: trace report #3"
363		} else {
364		    pass "12.3: trace report #3"
365		}
366	    }
367	}
368
369	gdb_tfind_test "12.4: tfind end, selects no frame" "end" "-1"
370	gdb_tfind_test "12.4: find first TDP #6 frame" "tracepoint $tdp6" \
371	    "\$tracepoint" "$tdp6"
372
373	set linecount6 0
374
375	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" {
376	    -re "TDP #$tdp6, frame $decimal: char_test = $arg1, long_test = $arg3" {
377		set linecount6 [expr $linecount6 + 1]
378		exp_continue
379	    }
380	    -re ".*$gdb_prompt $" {
381		if { ($linecount6 < 4) } {
382		    fail "12.4: trace report #4"
383		} else {
384		    pass "12.4: trace report #4"
385		}
386	    }
387	}
388
389	# There is always a thread of an inferior, either a live one or
390	# a faked one.
391	gdb_test "info threads" "\\* ${decimal}    (process|Thread) \[0-9\.\]+\[ \t\].*"
392	gdb_test "info inferiors" "\\* 1    process ${decimal} \[ \t\]+\[^\r\n\]*\[ \t\]+${binfile}.*"
393    }
394}
395
396use_collected_data "live"
397
398# Finished!
399gdb_tfind_test "finished: make sure not debugging any trace frame" \
400    "none" "-1"
401
402# Save trace frames to tfile.
403set tracefile [standard_output_file ${testfile}]
404gdb_test "tsave ${tracefile}.tf" \
405    "Trace data saved to file '${tracefile}.tf'.*" \
406    "save tfile trace file"
407
408# Save trace frames to ctf.
409gdb_test "tsave -ctf ${tracefile}.ctf" \
410    "Trace data saved to directory '${tracefile}.ctf'.*" \
411    "save ctf trace file"
412
413# Change target to tfile.
414set test "change to tfile target"
415gdb_test_multiple "target tfile ${tracefile}.tf" "$test" {
416    -re "A program is being debugged already.  Kill it. .y or n. " {
417	send_gdb "y\n"
418	exp_continue
419    }
420    -re "$gdb_prompt $" {
421	pass "$test"
422    }
423}
424# Test the collected trace frames from tfile.
425use_collected_data "tfile"
426
427# Try to read ctf data if GDB supports.
428gdb_test_multiple "target ctf ${tracefile}.ctf" "" {
429    -re "Undefined target command: \"ctf ${tracefile}.ctf\"\.  Try \"help target\"\.\r\n$gdb_prompt $" {
430    }
431    -re ".*\r\n$gdb_prompt $" {
432	use_collected_data "ctf"
433    }
434}
435