1# Copyright 1998, 2007, 2008, 2009, 2010, 2011 2# Free Software Foundation, Inc. 3# 4# This program is free software; you can redistribute it and/or modify 5# it under the terms of the GNU General Public License as published by 6# the Free Software Foundation; either version 3 of the License, or 7# (at your option) any later version. 8# 9# This program is distributed in the hope that it will be useful, 10# but WITHOUT ANY WARRANTY; without even the implied warranty of 11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12# GNU General Public License for more details. 13# 14# You should have received a copy of the GNU General Public License 15# along with this program. If not, see <http://www.gnu.org/licenses/>. 16 17# This file was written by Michael Snyder (msnyder@cygnus.com) 18 19load_lib "trace-support.exp"; 20 21if $tracelevel then { 22 strace $tracelevel 23} 24 25 26gdb_exit 27gdb_start 28 29set testfile "actions" 30set srcfile ${testfile}.c 31set binfile $objdir/$subdir/backtrace 32if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \ 33 executable {debug nowarnings}] != "" } { 34 untested backtrace.exp 35 return -1 36} 37gdb_load $binfile 38gdb_test "tstop" ".*" "" 39gdb_test "tfind none" ".*" "" 40runto_main 41gdb_reinitialize_dir $srcdir/$subdir 42 43# We generously give ourselves one "pass" if we successfully 44# detect that this test cannot be run on this target! 45if { ![gdb_target_supports_trace] } then { 46 pass "Current target does not support trace" 47 return 1; 48 49} 50 51# 52# test backtraces in trace frames 53# 54 55set testline1 0 56set testline2 0 57set testline3 0 58set testline4 0 59set testline5 0 60set testline6 0 61 62set arg1 1 63set arg2 2 64set arg3 3 65set arg4 4 66set arg5 5 67set arg6 6 68 69set baseline [gdb_find_recursion_test_baseline $srcfile]; 70if { $baseline == -1 } { 71 fail "Could not find gdb_recursion_test function" 72 return; 73} 74 75set return_me 0 76 77gdb_test_multiple "list $baseline, +12" "all tests in this module will fail" { 78 -re "\[\r\n\](\[0-9\]+).*gdbtestline 1 " { 79 set testline1 $expect_out(1,string) 80 exp_continue 81 } 82 -re "\[\r\n\](\[0-9\]+).*gdbtestline 2 " { 83 set testline2 $expect_out(1,string) 84 exp_continue 85 } 86 -re "\[\r\n\](\[0-9\]+).*gdbtestline 3 " { 87 set testline3 $expect_out(1,string) 88 exp_continue 89 } 90 -re "\[\r\n\](\[0-9\]+).*gdbtestline 4 " { 91 set testline4 $expect_out(1,string) 92 exp_continue 93 } 94 -re "\[\r\n\](\[0-9\]+).*gdbtestline 5 " { 95 set testline5 $expect_out(1,string) 96 exp_continue 97 } 98 -re "\[\r\n\](\[0-9\]+).*gdbtestline 6 " { 99 set testline6 $expect_out(1,string) 100 exp_continue 101 } 102 -re ".*$gdb_prompt $" { 103 if { ($testline1 == 0) || ($testline2 == 0) || ($testline3 == 0) || ($testline4 == 0) || ($testline5 == 0) || ($testline6 == 0) } { 104 untested backtrace.exp 105 set return_me 1 106all tests in this module will fail." 107 } 108 } 109 default { 110 untested backtrace.exp 111 set return_me 1 112all tests in this module will fail." 113 } 114} 115 116if { $return_me == 1 } then { 117 return -1; 118} 119 120# 121# Setup backtrace experiment. This will involve: 122# 1) a tracepoint where nothing is collected 123# 2) a tracepoint where only regs are collected 124# 3) a tracepoint where regs, locals and args are collected 125# 4) a tracepoint where regs plus some amount of stack are collected. 126# 127 128gdb_delete_tracepoints 129set tdp2 [gdb_gettpnum $testline2] 130set tdp3 [gdb_gettpnum $testline3] 131set tdp4 [gdb_gettpnum $testline4] 132set tdp5 [gdb_gettpnum $testline5] 133set tdp6 [gdb_gettpnum $testline6] 134if { $tdp2 <= 0 || $tdp3 <= 0 || \ 135 $tdp4 <= 0 || $tdp5 <= 0 || $tdp6 <= 0 } then { 136 fail "setting tracepoints failed" 137 return; 138} 139 140#gdb_trace_setactions "setup TP to collect FP" \ 141# "$tdp2" \ 142# "collect \$fp" "" 143# 144 145gdb_trace_setactions "8.6: setup TP to collect regs" \ 146 "$tdp3" \ 147 "collect \$regs" "^$" 148 149gdb_trace_setactions "8.6: setup TP to collect regs, args, and locals" \ 150 "$tdp4" \ 151 "collect \$regs, \$args, \$locs" "^$" 152 153if [istarget "x86_64-*"] then { 154 set fpreg "\$rbp" 155 set spreg "\$rsp" 156} elseif [istarget "i?86-*"] then { 157 set fpreg "\$ebp" 158 set spreg "\$esp" 159} else { 160 set fpreg "\$fp" 161 set spreg "\$sp" 162} 163 164gdb_trace_setactions "8.6: setup TP to collect stack mem cast expr" \ 165 "$tdp6" \ 166 "collect $fpreg, \(\*\(void \*\*\) \($spreg\)\) @ 64" "^$" 167 168gdb_test "tstart" ".*" "" 169 170gdb_test "break end" ".*" "" 171gdb_test "continue" \ 172 "Continuing.*Breakpoint $decimal, end.*" \ 173 "run trace experiment" 174 175gdb_test "tstop" ".*" "" 176 177proc gdb_backtrace_tdp_1 { msg } { 178 global gdb_prompt 179 180 # We are in a trace frame at which we didn't collect anything 181 # except $PC. Therefore we expect to be able to identify stack 182 # frame #0, but that's about all. In particular we do not expect 183 # to be able to display the function's arguments or locals, and we 184 # do not expect to be able to identify the caller of this function. 185 186 gdb_test "backtrace" \ 187 "#0\[\t \]+gdb_recursion_test.*depth=.*" \ 188 "$msg" 189} 190 191proc gdb_backtrace_tdp_2 { msg } { 192 global gdb_prompt 193 194 # We are in a trace frame at which we collected only the registers 195 # Therefore we expect to be able to identify stack frame #0, but 196 # we don't expect to be able to display its args unles they are 197 # passed in registers (which isn't the case for m68k), and we 198 # don't expect to be able to identify the caller's stack frame. 199 200 gdb_test "backtrace" \ 201 "#0\[\t \]+gdb_recursion_test.*depth=.*" \ 202 "$msg" 203} 204 205proc gdb_backtrace_tdp_3 { msg } { 206 global gdb_prompt 207 208 # We are in a trace frame at which we collected all registers, all 209 # arguments and all locals. This means that the display of 210 # stack frame #0 should be complete (including argument values). 211 212 gdb_test_multiple "backtrace" "$msg" { 213 -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 $" { 214 pass "$msg" 215 } 216 -re "#0\[\t \]+gdb_recursion_test.*depth=Cannot access.*$gdb_prompt $" { 217 fail "$msg (failed to collect arguments)" 218 } 219 } 220} 221 222proc gdb_backtrace_tdp_4 { msg depth } { 223 global gdb_prompt 224 225 # We are in a trace frame at which we collected all registers, 226 # plus a sizeable hunk of stack memory. This should enable us to 227 # display at least several stack frames worth of backtrace. We'll 228 # assume that if we can't display at least "depth" levels (with 229 # args), it counts as an error. 230 231 gdb_test_multiple "backtrace" "$msg" { 232 -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 $" { 233 pass "$msg" 234 } 235 -re "#$depth\[\t \].*gdb_recursion_test.*depth=.*$gdb_prompt $" { 236 fail "$msg (args missing from #$depth stack frame)" 237 } 238 -re "#\[0-9\]+\[\t \].*gdb_recursion_test.*depth=.*$gdb_prompt $" { 239 fail "$msg (fewer than $depth stack frames found)" 240 } 241 } 242} 243 244# 245# begin backtrace test 246# 247 248set timeout 60 249 250gdb_tfind_test "init: make sure not debugging any trace frame" "none" "-1" 251 252gdb_tfind_test "8.6: find start frame" "start" "0" 253gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \ 254 "TDP $tdp2:" "" 255gdb_backtrace_tdp_1 "8.6: Backtrace, depth == 1, collect nothing" 256 257gdb_tfind_test "8.6: find frame 1" "1" "1" 258gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \ 259 "TDP $tdp3:" "" 260gdb_backtrace_tdp_2 "8.6: Backtrace, depth == 1, collect regs" 261 262gdb_tfind_test "8.6: find frame 2" "2" "2" 263gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \ 264 "TDP $tdp4:" "" 265gdb_backtrace_tdp_3 "8.6: Backtrace, depth == 1, collect args and locals" 266 267 268gdb_tfind_test "8.6: find frame 4" "4" "4" 269gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \ 270 "TDP $tdp6:" "" 271gdb_backtrace_tdp_4 "8.6: Backtrace, depth == 1, collect stack mem expr" "0" 272 273gdb_tfind_test "8.6: find frame 5" "5" "5" 274gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \ 275 "TDP $tdp2:" "" 276gdb_backtrace_tdp_1 "8.6: Backtrace, depth == 2, collect nothing" 277 278gdb_tfind_test "8.6: find frame 6" "6" "6" 279gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \ 280 "TDP $tdp3:" "" 281gdb_backtrace_tdp_2 "8.6: Backtrace, depth == 2, collect regs" 282 283gdb_tfind_test "8.6: find frame 7" "7" "7" 284gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \ 285 "TDP $tdp4:" "" 286gdb_backtrace_tdp_3 "8.6: Backtrace, depth == 2, collect args and locals" 287 288 289gdb_tfind_test "8.6: find frame 9" "9" "9" 290gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \ 291 "TDP $tdp6:" "" 292gdb_backtrace_tdp_4 "8.6: Backtrace, depth == 1, collect stack mem expr" "0" 293 294gdb_tfind_test "8.6: find frame 10" "10" "10" 295gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \ 296 "TDP $tdp2:" "" 297gdb_backtrace_tdp_1 "8.6: Backtrace, depth == 3, collect nothing" 298 299gdb_tfind_test "8.6: find frame 11" "11" "11" 300gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \ 301 "TDP $tdp3:" "" 302gdb_backtrace_tdp_2 "8.6: Backtrace, depth == 3, collect regs" 303 304gdb_tfind_test "8.6: find frame 12" "12" "12" 305gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \ 306 "TDP $tdp4:" "" 307gdb_backtrace_tdp_3 "8.6: Backtrace, depth == 3, collect args and locals" 308 309 310gdb_tfind_test "8.6: find frame 14" "14" "14" 311gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \ 312 "TDP $tdp6:" "" 313gdb_backtrace_tdp_4 "8.6: Backtrace, depth == 1, collect stack mem expr" "0" 314 315gdb_tfind_test "8.6: find frame 15" "15" "15" 316gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \ 317 "TDP $tdp2:" "" 318gdb_backtrace_tdp_1 "8.6: Backtrace, depth == 4, collect nothing" 319 320gdb_tfind_test "8.6: find frame 16" "16" "16" 321gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \ 322 "TDP $tdp3:" "" 323gdb_backtrace_tdp_2 "8.6: Backtrace, depth == 4, collect regs" 324 325gdb_tfind_test "8.6: find frame 17" "17" "17" 326gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \ 327 "TDP $tdp4:" "" 328gdb_backtrace_tdp_3 "8.6: Backtrace, depth == 4, collect args and locals" 329 330 331gdb_tfind_test "8.6: find frame 19" "19" "19" 332gdb_test "printf \"TDP \%d:\\n\", \$tracepoint" \ 333 "TDP $tdp6:" "" 334gdb_backtrace_tdp_4 "8.6: Backtrace, depth == 1, collect stack mem expr" "0" 335 336gdb_test "printf \"x \%d x\\n\", depth == 3" \ 337 "x 0 x" \ 338 "1.13: trace in recursion: depth not equal to 3" 339 340# Finished! 341gdb_test "tfind none" ".*" "" 342