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