1 # Copyright
2004-2019 Free Software Foundation
, Inc.
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.
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.
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
/>.
16 # This test is to check that a frame
's "info frame", especially the
17 # saved registers list, doesn't change
while that frame isn
't current.
19 # It uses the program savedregs.c to construct a somewhat warped
20 # backtrace (contains both signal and dummy frames) and then, at each
21 # step checks that non-inner frames have consistent "info frame"
22 # output. Note that a frame's
"info frame" can only be captured after
23 # it is non
-current
(made a
call, interrupted
, ...
), this is because
24 # instructions executed to perform the
call may affect
"info frame"
27 if [target_info
exists gdb
,nosignals
] {
28 verbose
"Skipping savedregs.exp because of nosignals."
35 if { [gdb_compile
"${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
36 untested
"failed to compile"
41 clean_restart $
{binfile
}
44 if ![runto_main
] then {
45 fail
"can't run to main"
49 proc process_saved_regs
{ current inner outer
} {
54 # Skip the CURRENT frame.
58 # Run over the list of INNER frames capturing the
"info frame"
59 # output
for each. Both dummy and sigtramp frames need to be
60 # handled specially
: they
do not yet have correct function names
;
61 # and
for dummy frames won
't have saved registers. If there's a
62 # problem
, fail but capture the output anyway
, hopefully later
63 #
"info frame" requests for that same frame will at least fail in
64 # a consistent manner
(stops propogated fails
).
67 set saved_regs
($func
) "error"
68 set test
"get $func info frame"
69 # Both dummy and sigtramp frames have problems.
72 # Dummy frame
's do not have saved registers, and do
74 set pat "Stack frame at .*"
77 # Sigtramp frames don't yet print
<signal trampoline
>.
78 set pat
"Stack frame at .* Saved registers:.*"
81 set pat
"Stack frame at .* in $func .*( Saved registers:.*)?"
84 #
If the
"info frame" barf, capture the output anyway so that
85 # it does not cascade further failures.
86 gdb_test_multiple
"info frame $level" "$test" {
87 -re
"($pat)$gdb_prompt " {
88 set saved_regs
($func
) "$expect_out(1,string)"
91 -re
"(Stack frame at .*)$gdb_prompt " {
92 set saved_regs
($func
) "$expect_out(1,string)"
95 -re
"(Cannot access .*)$gdb_prompt " {
96 set saved_regs
($func
) "$expect_out(1,string)"
103 # Now iterate through the list of OUTER frames checking that the
104 #
"info frame" output from each still matches what was captured
105 # during an early query. To avoid cascading failures
, checking is
106 # abandoned after the first failure. The assumption is that
,
107 # since frames outer to the botched frame rely
on the botched
108 # frame
's info, those more outer frames are also botched. Besides
109 # we've got the failure we
're after.
112 foreach func $outer {
113 set test [concat "Check $func info frame; stack contains" \
114 $current $inner $outer]
117 set pat [string_to_regexp "$saved_regs($func)"]
118 gdb_test_multiple "info frame $level" "$test" {
119 -re "$pat$gdb_prompt " {
125 pass "$test (skipped)"
132 # Continue to the signal thrower, capture main's saved
-reg
info.
133 gdb_test
"advance thrower" "thrower .* at .*"
134 process_saved_regs thrower
{ main
} { }
136 #
Continue to the
signal catcher
, check main
's saved-reg info, capture
137 # catcher's saved
-reg
info.
138 gdb_test
"handle SIGSEGV pass print nostop"
139 gdb_test
"handle SIGILL pass print nostop"
140 gdb_test
"advance catcher" "catcher .* at .*"
141 process_saved_regs catcher
{ sigtramp thrower
} { main
}
143 # Breakpoint at and
call the caller function
, saved
-regs of main and
144 # catcher
, capture caller
's registers.
145 gdb_test "break caller"
146 gdb_test "call caller (1,2,3,4,5,6,7,8)"
147 process_saved_regs caller { dummy catcher } { sigtramp thrower main }
149 # Run to callee, again check everything.
150 gdb_test "advance callee" "callee .* at .*"
151 process_saved_regs callee { caller } { dummy catcher sigtramp thrower main }