1 # Copyright
2004-2024 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 require
{!target_info
exists gdb
,nosignals
}
32 if { [gdb_compile
"${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
33 untested
"failed to compile"
38 clean_restart $
{binfile
}
45 proc process_saved_regs
{ current inner outer
} {
50 # Skip the CURRENT frame.
54 # Run over the list of INNER frames capturing the
"info frame"
55 # output
for each. Both dummy and sigtramp frames need to be
56 # handled specially
: they
do not yet have correct function names
;
57 # and
for dummy frames won
't have saved registers. If there's a
58 # problem
, fail but capture the output anyway
, hopefully later
59 #
"info frame" requests for that same frame will at least fail in
60 # a consistent manner
(stops propagated fails
).
63 set saved_regs
($func
) "error"
64 set test
"get $func info frame"
65 # Both dummy and sigtramp frames have problems.
68 # Dummy frame
's do not have saved registers, and do
70 set pat "Stack frame at .*"
73 # Sigtramp frames don't yet print
<signal trampoline
>.
74 set pat
"Stack frame at .* Saved registers:.*"
77 set pat
"Stack frame at .* in $func .*( Saved registers:.*)?"
80 #
If the
"info frame" barf, capture the output anyway so that
81 # it does not cascade further failures.
82 gdb_test_multiple
"info frame $level" "$test" {
83 -re
"($pat)$gdb_prompt " {
84 set saved_regs
($func
) "$expect_out(1,string)"
87 -re
"(Stack frame at .*)$gdb_prompt " {
88 set saved_regs
($func
) "$expect_out(1,string)"
91 -re
"(Cannot access .*)$gdb_prompt " {
92 set saved_regs
($func
) "$expect_out(1,string)"
99 # Now iterate through the list of OUTER frames checking that the
100 #
"info frame" output from each still matches what was captured
101 # during an early query. To avoid cascading failures
, checking is
102 # abandoned after the first failure. The assumption is that
,
103 # since frames outer to the botched frame rely
on the botched
104 # frame
's info, those more outer frames are also botched. Besides
105 # we've got the failure we
're after.
108 foreach func $outer {
109 set test [concat "Check $func info frame; stack contains" \
110 $current $inner $outer]
113 set pat [string_to_regexp "$saved_regs($func)"]
114 gdb_test_multiple "info frame $level" "$test" {
115 -re "$pat$gdb_prompt " {
121 pass "$test (skipped)"
128 # Continue to the signal thrower, capture main's saved
-reg
info.
129 gdb_test
"advance thrower" "thrower .* at .*"
130 process_saved_regs thrower
{ main
} { }
132 #
Continue to the
signal catcher
, check main
's saved-reg info, capture
133 # catcher's saved
-reg
info.
134 gdb_test
"handle SIGSEGV pass print nostop"
135 gdb_test
"handle SIGILL pass print nostop"
136 gdb_test
"advance catcher" "catcher .* at .*"
137 process_saved_regs catcher
{ sigtramp thrower
} { main
}
139 # Breakpoint at and
call the caller function
, saved
-regs of main and
140 # catcher
, capture caller
's registers.
141 gdb_test "break caller"
142 gdb_test "call caller (1,2,3,4,5,6,7,8)"
143 process_saved_regs caller { dummy catcher } { sigtramp thrower main }
145 # Run to callee, again check everything.
146 gdb_test "advance callee" "callee .* at .*"
147 process_saved_regs callee { caller } { dummy catcher sigtramp thrower main }