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