1 # Copyright
2008-2023 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
/>.
17 # Test support
for stepping over longjmp.
23 if { [gdb_compile
"${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug nowarnings}] != "" } {
24 untested
"failed to compile"
28 proc do_test
{ with_probes
} {
29 clean_restart $
{::binfile
}
31 if { !$with_probes
} {
32 gdb_test
"maint ignore-probes libc ^longjmp$"
39 # With a libc with probes
, all tests should pass.
41 # Without probes
, we can still
set a
break on longjmp
, but getting the longjmp
42 # target may not work
, in the following cases
:
43 #
- gdbarch_get_longjmp_target_p
(gdbarch
) == 0: not implemented.
44 #
- gdbarch_get_longjmp_target
(gdbarch
) == 0: for instance
on amd64
if
45 # tdep
->jb_pc_offset
== -1.
46 #
- gdbarch_get_longjmp_target
(gdbarch
) != 0: if we have a glibc with
47 # pointer mangling
( https
://sourceware.org
/glibc
/wiki
/PointerEncryption
)
48 #
then we
retrieve a mangled longjmp target that needs to be demangled.
49 #
For instance
on amd64 with target board unix
/-m32.
51 # Pointer demangling is currently not implemented
for any target.
52 #
For the amd64 case
, this would require copying
for instance this
:
53 #
48 c1 ca
11 ror $
0x11,%rdx
54 #
64 48 33 14 25 30 00 xor
%fs
:0x30,%rdx
55 # into a scratch space
, save the register
set, set %rdx to the mangled
56 # longjmp target
, displaced
-step through the two insn and read the
57 # demangled longjmp target from
%rdx
, and restore the register
set.
59 # The failure
mode in the first two cases is that the next degrades into a
60 #
continue. The failure
mode in the latter case is a failure to
set a
61 # breakpoint
(matched by re_cannot_insert_bp
) and a stop in longjmp.
63 # We detect the different failure modes and kfail these.
65 set have_longjmp_probe
0
66 gdb_test_multiple
"info probes stap libc ^longjmp$" "" {
67 -re
-wrap
"No probes matched\\." {
70 -re
-wrap
"\r\nstap\[ \t\]+libc\[ \t\]+longjmp\[ \t\]+.*" {
72 set have_longjmp_probe
1
77 if { !$have_longjmp_probe
} {
78 unsupported
"longjmp probe required"
82 gdb_assert
{ !$have_longjmp_probe
}
85 # When using these line numbers in
break linespecs
, prefix each of these
86 # with
"$subdir/$srcfile:" to avoid referring to a glibc file when stopped
87 # in __libc_siglongjmp or similar.
88 set bp_miss_step_1
[gdb_get_line_number
"miss_step_1"]
89 set bp_miss_step_2
[gdb_get_line_number
"miss_step_2"]
91 set bp_start_test_1
[gdb_get_line_number
"patt1"]
92 set bp_start_test_2
[gdb_get_line_number
"patt2"]
93 set bp_start_test_3
[gdb_get_line_number
"patt3"]
95 set re_cannot_insert_bp \
98 "Cannot insert breakpoint $::decimal\\." \
99 "Cannot access memory at address $::hex"]
102 # Pattern
1 - simple longjmp.
105 with_test_prefix
"pattern 1" {
107 with_test_prefix setup
{
110 gdb_test
"break $::subdir/$::srcfile:$bp_start_test_1" \
111 "Breakpoint.*at.* file .*$::srcfile, line.*$bp_start_test_1.*" \
112 "breakpoint at pattern start"
113 gdb_test
"continue" "patt1.*" "continue to breakpoint at pattern start"
116 gdb_test
"break $::subdir/$::srcfile:$bp_miss_step_1" \
117 "Breakpoint.*at.* file .*$::srcfile, line.*$bp_miss_step_1.*" \
118 "breakpoint at safety net"
121 gdb_test
"next" "longjmps\\+\\+;.*" "next over setjmp"
122 gdb_test
"next" "longjmp \\(env, 1\\);.*" "next to longjmp"
124 set msg
"next over longjmp"
125 gdb_test_multiple
"next" $msg {
126 -re
".*patt1.*$::gdb_prompt $" {
128 gdb_test
"next" "resumes\\+\\+.*" "next into else block"
129 gdb_test
"next" "miss_step_1.*" "next into safety net"
131 -re
"miss_step_1.*$::gdb_prompt $" {
132 if { $have_longjmp_probe
} {
135 kfail $gdb_test_name
"gdb/26967"
138 -re
-wrap
"\r\n$re_cannot_insert_bp\r\n.*" {
139 if { $have_longjmp_probe
} {
142 kfail $gdb_test_name
"gdb/26967"
149 # Pattern
2 - longjmp from an inner function.
152 with_test_prefix
"pattern 2" {
154 with_test_prefix setup
{
157 gdb_test
"break $::subdir/$::srcfile:$bp_start_test_2" \
158 "Breakpoint.*at.* file .*$::srcfile, line.*$bp_start_test_2.*" \
159 "breakpoint at pattern start"
160 gdb_test
"continue" "patt2.*" "continue to breakpoint at pattern start"
163 gdb_test
"break $::subdir/$::srcfile:$bp_miss_step_2" \
164 "Breakpoint.*at.* file .*$::srcfile, line.*$bp_miss_step_2.*" \
165 "breakpoint at safety net"
168 gdb_test
"next" "call_longjmp.*" "next over setjmp"
170 set msg
"next over call_longjmp"
171 gdb_test_multiple
"next" $msg {
172 -re
".*patt2.*$::gdb_prompt $" {
175 gdb_test
"next" "resumes\\+\\+.*" "next into else block"
176 gdb_test
"next" "miss_step_2.*" "next into safety net"
178 -re
"miss_step_2.*$::gdb_prompt $" {
179 if { $have_longjmp_probe
} {
182 kfail $gdb_test_name
"gdb/26967"
185 -re
-wrap
"\r\n$re_cannot_insert_bp\r\n.*" {
186 if { $have_longjmp_probe
} {
189 kfail $gdb_test_name
"gdb/26967"
196 # Pattern
3 - setjmp
/longjmp inside stepped
-over function.
199 with_test_prefix
"pattern 3" {
201 with_test_prefix setup
{
204 gdb_test
"break $::subdir/$::srcfile:$bp_start_test_3" \
205 "Breakpoint.*at.* file .*$::srcfile, line.*$bp_start_test_3.*" \
206 "breakpoint at pattern start"
207 gdb_test
"continue" "patt3.*" "continue to breakpoint at pattern start"
210 gdb_test_multiple
"next" "next over pattern" {
211 -re
-wrap
"longjmp caught.*" {
214 -re
-wrap
"\r\n$re_cannot_insert_bp\r\n.*" {
215 if { $have_longjmp_probe
} {
218 kfail $gdb_test_name
"gdb/26967"
225 foreach_with_prefix with_probes
{ 0 1 } {