xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/testsuite/gdb.trace/backtrace.exp (revision 8b657b0747480f8989760d71343d6dd33f8d4cf9)
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
20standard_testfile actions.c
21set executable $testfile
22set expfile $testfile.exp
23
24if ![gdb_trace_common_supports_arch] {
25    unsupported "no trace-common.h support for arch"
26    return -1
27}
28
29if [prepare_for_testing "failed to prepare" $executable $srcfile \
30	[list debug nowarnings nopie]] {
31    return -1
32}
33
34if ![runto_main] {
35    return -1
36}
37
38if {![gdb_target_supports_trace]} {
39    unsupported "current target does not support trace"
40    return 1
41
42}
43
44#
45# test backtraces in trace frames
46#
47
48set testline1 0
49set testline2 0
50set testline3 0
51set testline4 0
52set testline5 0
53set testline6 0
54
55set arg1 1
56set arg2 2
57set arg3 3
58set arg4 4
59set arg5 5
60set arg6 6
61
62set baseline [gdb_find_recursion_test_baseline $srcfile]
63if { $baseline == -1 } {
64    fail "could not find gdb_recursion_test function"
65    return
66}
67
68set return_me 0
69
70gdb_test_multiple "list $baseline, +12" "all tests in this module will fail" {
71    -re "\[\r\n\](\[0-9\]+).*gdbtestline 1 " {
72	set testline1 $expect_out(1,string)
73	exp_continue
74    }
75    -re "\[\r\n\](\[0-9\]+).*gdbtestline 2 " {
76	set testline2 $expect_out(1,string)
77	exp_continue
78    }
79    -re "\[\r\n\](\[0-9\]+).*gdbtestline 3 " {
80	set testline3 $expect_out(1,string)
81	exp_continue
82    }
83    -re "\[\r\n\](\[0-9\]+).*gdbtestline 4 " {
84	set testline4 $expect_out(1,string)
85	exp_continue
86    }
87    -re "\[\r\n\](\[0-9\]+).*gdbtestline 5 " {
88	set testline5 $expect_out(1,string)
89	exp_continue
90    }
91    -re "\[\r\n\](\[0-9\]+).*gdbtestline 6 " {
92	set testline6 $expect_out(1,string)
93	exp_continue
94    }
95    -re ".*$gdb_prompt $" {
96	if { ($testline1 == 0) || ($testline2 == 0) || ($testline3 == 0) || ($testline4 == 0) || ($testline5 == 0) || ($testline6 == 0) } {
97	    untested "unexpected testline values"
98	    set return_me 1
99all tests in this module will fail."
100	}
101    }
102    default {
103	    untested "couldn't match pattern"
104	    set return_me 1
105all tests in this module will fail."
106    }
107}
108
109if {$return_me == 1} {
110    return -1
111}
112
113#
114# Setup backtrace experiment.  This will involve:
115#   1) a tracepoint where nothing is collected
116#   2) a tracepoint where only regs are collected
117#   3) a tracepoint where regs, locals and args are collected
118#   4) a tracepoint where regs plus some amount of stack are collected.
119#
120
121gdb_delete_tracepoints
122set tdp2 [gdb_gettpnum $testline2]
123set tdp3 [gdb_gettpnum $testline3]
124set tdp4 [gdb_gettpnum $testline4]
125set tdp5 [gdb_gettpnum $testline5]
126set tdp6 [gdb_gettpnum $testline6]
127if {    $tdp2 <= 0 || $tdp3 <= 0 || \
128	$tdp4 <= 0 || $tdp5 <= 0 || $tdp6 <= 0 } then {
129    fail "setting tracepoints failed"
130    return
131}
132
133#gdb_trace_setactions "setup TP to collect FP" \
134#	"$tdp2" \
135#	"collect \$fp" ""
136#
137
138gdb_trace_setactions "8.6: setup TP to collect regs" \
139	"$tdp3" \
140	"collect \$regs" "^$"
141
142gdb_trace_setactions "8.6: setup TP to collect regs, args, and locals" \
143	"$tdp4" \
144	"collect \$regs, \$args, \$locs" "^$"
145
146gdb_trace_setactions "8.6: setup TP to collect stack mem cast expr" \
147       "$tdp6" \
148       "collect \$$fpreg, \(\*\(void \*\*\) \(\$$spreg\)\) @ 128" "^$"
149
150gdb_test_no_output "tstart" ""
151
152gdb_breakpoint "end" qualified
153gdb_test "continue" \
154    "Continuing.*Breakpoint $decimal, end.*" \
155    "run trace experiment"
156
157gdb_test_no_output "tstop" ""
158
159proc gdb_backtrace_tdp_1 { msg } {
160    global gdb_prompt
161
162    # We are in a trace frame at which we didn't collect anything
163    # except $PC.  Therefore we expect to be able to identify stack
164    # frame #0, but that's about all.  In particular we do not expect
165    # to be able to display the function's arguments or locals, and we
166    # do not expect to be able to identify the caller of this function.
167
168    gdb_test "backtrace" \
169	"#0\[\t \]+gdb_recursion_test.*depth=.*" \
170	"$msg"
171}
172
173proc gdb_backtrace_tdp_2 { msg } {
174    global gdb_prompt
175
176    # We are in a trace frame at which we collected only the registers
177    # Therefore we expect to be able to identify stack frame #0, but
178    # we don't expect to be able to display its args unles they are
179    # passed in registers (which isn't the case for m68k), and we
180    # don't expect to be able to identify the caller's stack frame.
181
182    gdb_test "backtrace" \
183	"#0\[\t \]+gdb_recursion_test.*depth=.*" \
184	"$msg"
185}
186
187proc gdb_backtrace_tdp_3 { msg } {
188    global gdb_prompt
189
190    # We are in a trace frame at which we collected all registers, all
191    # arguments and all locals.  This means that the display of
192    # stack frame #0 should be complete (including argument values).
193
194    gdb_test_multiple "backtrace" "$msg" {
195	-re "#0\[\t \]+gdb_recursion_test.*depth=\[0-9\]+.*q1=\[0-9\]+.*q2=\[0-9\]+.*q3=\[0-9\]+.*q4=\[0-9\]+.*q5=\[0-9\]+.*q6=\[0-9\]+.*$gdb_prompt $" {
196	    pass "$msg"
197	}
198	-re "#0\[\t \]+gdb_recursion_test.*depth=Cannot access.*$gdb_prompt $" {
199	    fail "$msg (failed to collect arguments)"
200	}
201    }
202}
203
204proc gdb_backtrace_tdp_4 { msg depth traceframe } {
205    global gdb_prompt
206
207    with_test_prefix "traceframe $traceframe" {
208	# We are in a trace frame at which we collected all registers,
209	# plus a sizeable hunk of stack memory.  This should enable us to
210	# display at least several stack frames worth of backtrace.  We'll
211	# assume that if we can't display at least "depth" levels (with
212	# args), it counts as an error.
213
214	gdb_test_multiple "backtrace" "$msg" {
215	    -re "#$depth\[\t \].*gdb_recursion_test.*depth=\[0-9\]+.*q1=\[0-9\]+.*q2=\[0-9\]+.*q3=\[0-9\]+.*q4=\[0-9\]+.*q5=\[0-9\]+.*q6=\[0-9\]+.*$gdb_prompt $" {
216		pass "$msg"
217	    }
218	    -re "#$depth\[\t \].*gdb_recursion_test.*depth=.*$gdb_prompt $" {
219		fail "$msg (args missing from #$depth stack frame)"
220	    }
221	    -re "#\[0-9\]+\[\t \].*gdb_recursion_test.*depth=.*$gdb_prompt $" {
222		fail "$msg (fewer than $depth stack frames found)"
223	    }
224	}
225
226	set output_string0 ""
227	# Match the output of command 'tdump' and save it in
228	# $output_string0.
229	set test "tdump on frame 0"
230	gdb_test_multiple "tdump" $test {
231	    -re "tdump\[\r\n\]+(.*)\[\r\n\]+$gdb_prompt $" {
232		set output_string0 $expect_out(1,string)
233	    }
234	}
235
236	gdb_test "up" ".*" ""
237
238	# Test that command 'tdump' still works properly when the
239	# selected frame is not the current frame, and save the output
240	# in $output_string1.
241	set test "tdump on frame 1"
242	set output_string1 ""
243	gdb_test_multiple "tdump" $test {
244	    -re "tdump\[\r\n\]+(.*)\[\r\n\]+$gdb_prompt $" {
245		set output_string1 $expect_out(1,string)
246	    }
247	}
248
249	# Output of 'tdump' on frame 0 and frame 1 should be
250	# identical.
251	gdb_assert ![string compare $output_string0 $output_string1] \
252	    "tdump output"
253    }
254}
255
256#
257# begin backtrace test
258#
259
260set timeout 60
261
262gdb_tfind_test "init: make sure not debugging any trace frame" "none" "-1"
263
264gdb_tfind_test "8.6: find start frame" "start" "0"
265gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \
266	"TDP $tdp2:" "printf TDP start"
267gdb_backtrace_tdp_1 "8.6: Backtrace, depth == 1, collect nothing"
268
269gdb_tfind_test "8.6: find frame 1"     "1" "1"
270gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \
271	"TDP $tdp3:" "printf TDP frame 1"
272gdb_backtrace_tdp_2 "8.6: Backtrace, depth == 1, collect regs"
273
274gdb_tfind_test "8.6: find frame 2"     "2" "2"
275gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \
276	"TDP $tdp4:" "printf TDP frame 2"
277gdb_backtrace_tdp_3 "8.6: Backtrace, depth == 1, collect args and locals"
278
279
280gdb_tfind_test "8.6: find frame 4"     "4" "4"
281gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \
282	"TDP $tdp6:" "printf TDP frame 4"
283gdb_backtrace_tdp_4 "8.6: Backtrace, depth == 1, collect stack mem expr" "0" 4
284
285gdb_tfind_test "8.6: find frame 5"     "5" "5"
286gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \
287	"TDP $tdp2:" "printf TDP frame 5"
288gdb_backtrace_tdp_1 "8.6: Backtrace, depth == 2, collect nothing"
289
290gdb_tfind_test "8.6: find frame 6"     "6" "6"
291gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \
292	"TDP $tdp3:" "printf TDP frame 6"
293gdb_backtrace_tdp_2 "8.6: Backtrace, depth == 2, collect regs"
294
295gdb_tfind_test "8.6: find frame 7"     "7" "7"
296gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \
297	"TDP $tdp4:" "printf TDP frame 7"
298gdb_backtrace_tdp_3 "8.6: Backtrace, depth == 2, collect args and locals"
299
300
301gdb_tfind_test "8.6: find frame 9"     "9" "9"
302gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \
303	"TDP $tdp6:" "printf TDP frame 9"
304gdb_backtrace_tdp_4 "8.6: Backtrace, depth == 1, collect stack mem expr" "0" 9
305
306gdb_tfind_test "8.6: find frame 10"    "10" "10"
307gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \
308	"TDP $tdp2:" "printf TDP frame 10"
309gdb_backtrace_tdp_1 "8.6: Backtrace, depth == 3, collect nothing"
310
311gdb_tfind_test "8.6: find frame 11"    "11" "11"
312gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \
313	"TDP $tdp3:" "printf TDP frame 11"
314gdb_backtrace_tdp_2 "8.6: Backtrace, depth == 3, collect regs"
315
316gdb_tfind_test "8.6: find frame 12"    "12" "12"
317gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \
318	"TDP $tdp4:" "printf TDP frame 12"
319gdb_backtrace_tdp_3 "8.6: Backtrace, depth == 3, collect args and locals"
320
321
322gdb_tfind_test "8.6: find frame 14"    "14" "14"
323gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \
324	"TDP $tdp6:" "printf TDP frame 14"
325gdb_backtrace_tdp_4 "8.6: Backtrace, depth == 1, collect stack mem expr" "0" 14
326
327gdb_tfind_test "8.6: find frame 15"    "15" "15"
328gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \
329	"TDP $tdp2:" "printf TDP frame 15"
330gdb_backtrace_tdp_1 "8.6: Backtrace, depth == 4, collect nothing"
331
332gdb_tfind_test "8.6: find frame 16"    "16" "16"
333gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \
334	"TDP $tdp3:" "printf TDP frame 16"
335gdb_backtrace_tdp_2 "8.6: Backtrace, depth == 4, collect regs"
336
337gdb_tfind_test "8.6: find frame 17"    "17" "17"
338gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \
339	"TDP $tdp4:" "printf TDP frame 17"
340gdb_backtrace_tdp_3 "8.6: Backtrace, depth == 4, collect args and locals"
341
342
343gdb_tfind_test "8.6: find frame 19"    "19" "19"
344gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \
345	"TDP $tdp6:" "printf TDP frame 19"
346gdb_backtrace_tdp_4 "8.6: Backtrace, depth == 1, collect stack mem expr" "0" 19
347
348gdb_test "printf \"x \%d x\\n\", depth == 3" \
349	"x 0 x" \
350	"1.13: trace in recursion: depth not equal to 3"
351
352# Finished!
353gdb_test "tfind none" ".*"
354