errno.exp revision 1.1.1.1 1 1.1 christos # Copyright 2024 Free Software Foundation, Inc.
2 1.1 christos # This program is free software; you can redistribute it and/or modify
3 1.1 christos # it under the terms of the GNU General Public License as published by
4 1.1 christos # the Free Software Foundation; either version 3 of the License, or
5 1.1 christos # (at your option) any later version.
6 1.1 christos #
7 1.1 christos # This program is distributed in the hope that it will be useful,
8 1.1 christos # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 1.1 christos # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 1.1 christos # GNU General Public License for more details.
11 1.1 christos
12 1.1 christos # Check that errno can be accessed by GDB under a variety of
13 1.1 christos # circumstances.
14 1.1 christos #
15 1.1 christos # The challenge with GDB accessing errno is that, on modern systems,
16 1.1 christos # errno is a variable in thread-local storage. So, if GDB's access to
17 1.1 christos # thread local storage is broken or unavailable, some of these tests
18 1.1 christos # could fail. On Linux, this is/was known to happen on systems with
19 1.1 christos # older versions of glibc as well as when debugging statically linked
20 1.1 christos # binaries.
21 1.1 christos #
22 1.1 christos # Another possibility is that the environment lacks sufficient
23 1.1 christos # type information to print errno. This can happen for the errno
24 1.1 christos # variable itself or when the debuginfo contains a macro for errno
25 1.1 christos # which refers to a function lacking type information.
26 1.1 christos #
27 1.1 christos # When debugging core files, access to errno might not be possible
28 1.1 christos # both due to the situations described earlier along with the fact
29 1.1 christos # that inferior function calls are not possible (for the cases in
30 1.1 christos # which errno is a macro which calls a function returning errno's
31 1.1 christos # address).
32 1.1 christos #
33 1.1 christos # It's also possible for a program to declare errno in an inner scope
34 1.1 christos # causing the thread-local errno to be shadowed. GDB should still
35 1.1 christos # correctly print the masking errno for this case.
36 1.1 christos #
37 1.1 christos # At the time that this test was written, on GNU/Linux and on FreeBSD,
38 1.1 christos # there were always scenarios in which printing errno was problematic.
39 1.1 christos # This test attempts to identify the problem cases and set up xfails
40 1.1 christos # for them. So, hopefully, there should be no actual failures. But
41 1.1 christos # the "expected" failures encountered by running this test do
42 1.1 christos # genuinely illustrate problems that a user might encounter while
43 1.1 christos # attempting to print errno.
44 1.1 christos
45 1.1 christos standard_testfile
46 1.1 christos
47 1.1 christos proc do_tests {{do_xfail_cast 0} {do_xfail 0} {do_xfail_core_test 0}} {
48 1.1 christos clean_restart $::binfile
49 1.1 christos if ![runto_main] {
50 1.1 christos return
51 1.1 christos }
52 1.1 christos
53 1.1 christos gdb_breakpoint [gdb_get_line_number "main-breakpoint"]
54 1.1 christos gdb_continue_to_breakpoint "main-breakpoint"
55 1.1 christos
56 1.1 christos # Whether or not "print errno" will work often depends on the
57 1.1 christos # debuginfo available. We can make some inferences about whether
58 1.1 christos # some of the tests should have xfail set-up by looking at the
59 1.1 christos # output of "ptype errno". This test is set up to always pass
60 1.1 christos # even for less than ideal outputs, because the point is to set up
61 1.1 christos # the xfail(s).
62 1.1 christos gdb_test_multiple "ptype errno" "check errno type availability" {
63 1.1 christos -re -wrap "type = int" {
64 1.1 christos pass $gdb_test_name
65 1.1 christos }
66 1.1 christos -re -wrap "type = .*no debug info.*" {
67 1.1 christos pass $gdb_test_name
68 1.1 christos set do_xfail 1
69 1.1 christos set do_xfail_core_test 1
70 1.1 christos }
71 1.1 christos -re -wrap "Cannot find thread-local variables on this target.*" {
72 1.1 christos pass $gdb_test_name
73 1.1 christos set do_xfail 1
74 1.1 christos set do_xfail_core_test 1
75 1.1 christos set do_xfail_cast 1
76 1.1 christos }
77 1.1 christos -re -wrap "Cannot find thread-local storage.*" {
78 1.1 christos pass $gdb_test_name
79 1.1 christos set do_xfail 1
80 1.1 christos set do_xfail_core_test 1
81 1.1 christos set do_xfail_cast 1
82 1.1 christos }
83 1.1 christos -re -wrap "has unknown return type; cast the call to its declared return type.*" {
84 1.1 christos
85 1.1 christos # On systems which glibc as the C library, using -g3,
86 1.1 christos # which causes macro information to be included in the
87 1.1 christos # debuginfo, errno might be defined as follows:
88 1.1 christos #
89 1.1 christos # #define errno (*__errno_location ())
90 1.1 christos #
91 1.1 christos # So, when we do "ptype errno", due to macro expansion,
92 1.1 christos # this ends up being "ptype (*__errno_location ())". So
93 1.1 christos # the call to __errno_location (or something similar on
94 1.1 christos # other OSes) is the call mentioned in the error message.
95 1.1 christos
96 1.1 christos pass $gdb_test_name
97 1.1 christos set do_xfail 1
98 1.1 christos set do_xfail_core_test 1
99 1.1 christos set do_xfail_cast 1
100 1.1 christos }
101 1.1 christos }
102 1.1 christos
103 1.1 christos # If errno is defined as a macro that contains an obvious function
104 1.1 christos # call, it won't work when debugging a core file.
105 1.1 christos gdb_test_multiple "info macro errno" "check if errno is a macro" {
106 1.1 christos -re -wrap "Defined at.*\[\r\n\]#define.*\\\(\\\).*" {
107 1.1 christos set do_xfail_core_test 1
108 1.1 christos pass $gdb_test_name
109 1.1 christos }
110 1.1 christos -re -wrap "Defined at.*\[\r\n\]#define.*" {
111 1.1 christos pass $gdb_test_name
112 1.1 christos }
113 1.1 christos -re -wrap "The symbol .errno. has no definition.*" {
114 1.1 christos pass $gdb_test_name
115 1.1 christos }
116 1.1 christos }
117 1.1 christos
118 1.1 christos # Sometimes, "ptype errno" will ferret out that thread local
119 1.1 christos # variables aren't accessible, but sometimes it won't. Dig deeper
120 1.1 christos # by trying to access memory using the "x/d" command. Again, the
121 1.1 christos # point here is to set up an xfail for the later tests, so we pass
122 1.1 christos # this test for other known outputs.
123 1.1 christos gdb_test_multiple "x/d &errno" "attempt to access errno memory" {
124 1.1 christos -re -wrap "Cannot find thread-local variables on this target.*" {
125 1.1 christos pass $gdb_test_name
126 1.1 christos set do_xfail 1
127 1.1 christos set do_xfail_core_test 1
128 1.1 christos set do_xfail_cast 1
129 1.1 christos }
130 1.1 christos -re -wrap "Cannot find thread-local storage.*" {
131 1.1 christos pass $gdb_test_name
132 1.1 christos set do_xfail 1
133 1.1 christos set do_xfail_core_test 1
134 1.1 christos set do_xfail_cast 1
135 1.1 christos }
136 1.1 christos -re -wrap "has unknown return type; cast the call to its declared return type.*" {
137 1.1 christos set do_xfail 1
138 1.1 christos set do_xfail_core_test 1
139 1.1 christos set do_xfail_cast 1
140 1.1 christos pass $gdb_test_name
141 1.1 christos }
142 1.1 christos -re -wrap "$::hex.*?:\[\t \]$::decimal" {
143 1.1 christos pass $gdb_test_name
144 1.1 christos }
145 1.1 christos }
146 1.1 christos
147 1.1 christos if $do_xfail {
148 1.1 christos setup_xfail *-*-*
149 1.1 christos }
150 1.1 christos gdb_test "print errno" ".* = 42"
151 1.1 christos
152 1.1 christos if $do_xfail_cast {
153 1.1 christos setup_xfail *-*-*
154 1.1 christos }
155 1.1 christos gdb_test "print (int) errno" ".* = 42"
156 1.1 christos
157 1.1 christos set corefile ${::binfile}.core
158 1.1 christos set core_supported 0
159 1.1 christos if { ![is_remote host] } {
160 1.1 christos set core_supported [gdb_gcore_cmd $corefile "save corefile"]
161 1.1 christos }
162 1.1 christos # Normally, we'd check core_supported here and return if it's
163 1.1 christos # not, but we'll defer that until after the shadow test.
164 1.1 christos
165 1.1 christos gdb_breakpoint [gdb_get_line_number "shadow_errno-breakpoint"]
166 1.1 christos gdb_continue_to_breakpoint "shadow_errno-breakpoint"
167 1.1 christos
168 1.1 christos # This test demonstrates why a simple hack to GDB for printing
169 1.1 christos # errno is a bad idea. (The hack was to intercept the string
170 1.1 christos # "errno" in process_print_command_args() and replace it with
171 1.1 christos # "*(*(int *(*)(void)) __errno_location) ()".)
172 1.1 christos gdb_test "print errno" ".* = 36" "print masking errno"
173 1.1 christos
174 1.1 christos # Finish test early if no core file was made.
175 1.1 christos if !$core_supported {
176 1.1 christos return
177 1.1 christos }
178 1.1 christos
179 1.1 christos clean_restart $::binfile
180 1.1 christos
181 1.1 christos set core_loaded [gdb_core_cmd $corefile "load corefile"]
182 1.1 christos if { $core_loaded == -1 } {
183 1.1 christos return
184 1.1 christos }
185 1.1 christos if $do_xfail_core_test {
186 1.1 christos setup_xfail *-*-*
187 1.1 christos }
188 1.1 christos gdb_test "print errno" ".* = 42" "check errno value from corefile"
189 1.1 christos }
190 1.1 christos
191 1.1 christos set binprefix $binfile
192 1.1 christos
193 1.1 christos with_test_prefix "default" {
194 1.1 christos set binfile $binprefix-default
195 1.1 christos if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
196 1.1 christos untested "failed to compile"
197 1.1 christos } else {
198 1.1 christos do_tests
199 1.1 christos }
200 1.1 christos }
201 1.1 christos
202 1.1 christos with_test_prefix "macros" {
203 1.1 christos set binfile $binprefix-macros
204 1.1 christos if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug macros}] != "" } {
205 1.1 christos untested "failed to compile"
206 1.1 christos } else {
207 1.1 christos do_tests
208 1.1 christos }
209 1.1 christos }
210 1.1 christos
211 1.1 christos with_test_prefix "static" {
212 1.1 christos set binfile $binprefix-static
213 1.1 christos if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug "additional_flags=-static"}] != "" } {
214 1.1 christos untested "failed to compile"
215 1.1 christos } else {
216 1.1 christos do_tests
217 1.1 christos }
218 1.1 christos }
219 1.1 christos
220 1.1 christos with_test_prefix "static-macros" {
221 1.1 christos set binfile $binprefix-static-macros
222 1.1 christos if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug macros "additional_flags=-static"}] != "" } {
223 1.1 christos untested "failed to compile"
224 1.1 christos } else {
225 1.1 christos do_tests
226 1.1 christos }
227 1.1 christos }
228 1.1 christos
229 1.1 christos with_test_prefix "pthreads" {
230 1.1 christos set binfile $binprefix-pthreads
231 1.1 christos if { [gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
232 1.1 christos untested "failed to compile"
233 1.1 christos } else {
234 1.1 christos do_tests
235 1.1 christos }
236 1.1 christos }
237 1.1 christos
238 1.1 christos with_test_prefix "pthreads-macros" {
239 1.1 christos set binfile $binprefix-pthreads-macros
240 1.1 christos if { [gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug macros}] != "" } {
241 1.1 christos untested "failed to compile"
242 1.1 christos } else {
243 1.1 christos do_tests
244 1.1 christos }
245 1.1 christos }
246 1.1 christos
247 1.1 christos with_test_prefix "pthreads-static" {
248 1.1 christos set binfile $binprefix-pthreads-static
249 1.1 christos if { [gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug "additional_flags=-static"}] != "" } {
250 1.1 christos untested "failed to compile"
251 1.1 christos } else {
252 1.1 christos do_tests
253 1.1 christos }
254 1.1 christos }
255 1.1 christos
256 1.1 christos with_test_prefix "pthreads-static-macros" {
257 1.1 christos set binfile $binprefix-pthreads-static-macros
258 1.1 christos if { [gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug macros "additional_flags=-static"}] != "" } {
259 1.1 christos untested "failed to compile"
260 1.1 christos } else {
261 1.1 christos do_tests
262 1.1 christos }
263 1.1 christos }
264