Update copyright year range in all GDB files.
[deliverable/binutils-gdb.git] / gdb / testsuite / gdb.base / ptype-offsets.exp
1 # This testcase is part of GDB, the GNU debugger.
2
3 # Copyright 2017-2020 Free Software Foundation, Inc.
4
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 # This testcase exercises the "ptype /o" feature, which can be used to
19 # print the offsets and sizes of each field of a struct/union/class.
20
21 standard_testfile .cc
22
23 # Test only works on LP64 targets. That's how we guarantee that the
24 # expected holes will be present in the struct.
25 if { ![is_lp64_target] } {
26 untested "test work only on lp64 targets"
27 return 0
28 }
29
30 if { [prepare_for_testing "failed to prepare" $testfile $srcfile \
31 { debug c++ }] } {
32 return -1
33 }
34
35 # Test general offset printing, ctor/dtor printing, union, formatting.
36 gdb_test "ptype /o struct abc" \
37 [string_to_regexp [multi_line \
38 "/* offset | size */ type = struct abc \{" \
39 " public:" \
40 "/* 8 | 8 */ void *field1;" \
41 "/* 16: 0 | 4 */ unsigned int field2 : 1;" \
42 "/* XXX 7-bit hole */" \
43 "/* XXX 3-byte hole */" \
44 "/* 20 | 4 */ int field3;" \
45 "/* 24 | 1 */ signed char field4;" \
46 "/* XXX 7-byte hole */" \
47 "/* 32 | 8 */ uint64_t field5;" \
48 "/* 40 | 8 */ union \{" \
49 "/* 8 */ void *field6;" \
50 "/* 4 */ int field7;" \
51 "" \
52 " /* total size (bytes): 8 */" \
53 " \} field8;" \
54 "/* 48 | 2 */ my_int_type field9;" \
55 "/* XXX 6-byte padding */" \
56 "" \
57 " /* total size (bytes): 56 */" \
58 " \}"]]
59
60 # Test "ptype /oTM".
61 gdb_test "ptype /oTM struct abc" \
62 [string_to_regexp [multi_line \
63 "/* offset | size */ type = struct abc \{" \
64 " public:" \
65 "/* 8 | 8 */ void *field1;" \
66 "/* 16: 0 | 4 */ unsigned int field2 : 1;" \
67 "/* XXX 7-bit hole */" \
68 "/* XXX 3-byte hole */" \
69 "/* 20 | 4 */ int field3;" \
70 "/* 24 | 1 */ signed char field4;" \
71 "/* XXX 7-byte hole */" \
72 "/* 32 | 8 */ uint64_t field5;" \
73 "/* 40 | 8 */ union \{" \
74 "/* 8 */ void *field6;" \
75 "/* 4 */ int field7;" \
76 "" \
77 " /* total size (bytes): 8 */" \
78 " \} field8;" \
79 "/* 48 | 2 */ my_int_type field9;" \
80 "" \
81 " abc(void);" \
82 " ~abc();" \
83 "" \
84 " typedef short my_int_type;" \
85 "/* XXX 6-byte padding */" \
86 "" \
87 " /* total size (bytes): 56 */" \
88 " \}"]]
89
90 # Test "ptype /TMo". This should be the same as "ptype /o".
91 gdb_test "ptype /TMo struct abc" \
92 [string_to_regexp [multi_line \
93 "/* offset | size */ type = struct abc \{" \
94 " public:" \
95 "/* 8 | 8 */ void *field1;" \
96 "/* 16: 0 | 4 */ unsigned int field2 : 1;" \
97 "/* XXX 7-bit hole */" \
98 "/* XXX 3-byte hole */" \
99 "/* 20 | 4 */ int field3;" \
100 "/* 24 | 1 */ signed char field4;" \
101 "/* XXX 7-byte hole */" \
102 "/* 32 | 8 */ uint64_t field5;" \
103 "/* 40 | 8 */ union \{" \
104 "/* 8 */ void *field6;" \
105 "/* 4 */ int field7;" \
106 "" \
107 " /* total size (bytes): 8 */" \
108 " \} field8;" \
109 "/* 48 | 2 */ my_int_type field9;" \
110 "/* XXX 6-byte padding */" \
111 "" \
112 " /* total size (bytes): 56 */" \
113 " \}"]]
114
115 # Test nested structs.
116 gdb_test "ptype /o struct pqr" \
117 [string_to_regexp [multi_line \
118 "/* offset | size */ type = struct pqr \{" \
119 "/* 0 | 4 */ int ff1;" \
120 "/* XXX 4-byte hole */" \
121 "/* 8 | 40 */ struct xyz \{" \
122 "/* 8 | 4 */ int f1;" \
123 "/* 12 | 1 */ signed char f2;" \
124 "/* XXX 3-byte hole */" \
125 "/* 16 | 8 */ void *f3;" \
126 "/* 24 | 24 */ struct tuv \{" \
127 "/* 24 | 4 */ int a1;" \
128 "/* XXX 4-byte hole */" \
129 "/* 32 | 8 */ signed char *a2;" \
130 "/* 40 | 4 */ int a3;" \
131 "/* XXX 4-byte padding */" \
132 "" \
133 " /* total size (bytes): 24 */" \
134 " \} f4;" \
135 "" \
136 " /* total size (bytes): 40 */" \
137 " \} ff2;" \
138 "/* 48 | 1 */ signed char ff3;" \
139 "/* XXX 7-byte padding */" \
140 "" \
141 " /* total size (bytes): 56 */" \
142 " \}"]]
143
144 # Test that the offset is properly reset when we are printing a union
145 # and go inside two inner structs.
146 # This also tests a struct inside a struct inside a union.
147 gdb_test "ptype /o union qwe" \
148 [string_to_regexp [multi_line \
149 "/* offset | size */ type = union qwe \{" \
150 "/* 24 */ struct tuv \{" \
151 "/* 0 | 4 */ int a1;" \
152 "/* XXX 4-byte hole */" \
153 "/* 8 | 8 */ signed char *a2;" \
154 "/* 16 | 4 */ int a3;" \
155 "/* XXX 4-byte padding */" \
156 "" \
157 " /* total size (bytes): 24 */" \
158 " \} fff1;" \
159 "/* 40 */ struct xyz \{" \
160 "/* 0 | 4 */ int f1;" \
161 "/* 4 | 1 */ signed char f2;" \
162 "/* XXX 3-byte hole */" \
163 "/* 8 | 8 */ void *f3;" \
164 "/* 16 | 24 */ struct tuv \{" \
165 "/* 16 | 4 */ int a1;" \
166 "/* XXX 4-byte hole */" \
167 "/* 24 | 8 */ signed char *a2;" \
168 "/* 32 | 4 */ int a3;" \
169 "/* XXX 4-byte padding */" \
170 "" \
171 " /* total size (bytes): 24 */" \
172 " \} f4;" \
173 "" \
174 " /* total size (bytes): 40 */" \
175 " \} fff2;" \
176 "" \
177 " /* total size (bytes): 40 */" \
178 " \}"]]
179
180 # Test printing a struct that contains a union, and that also
181 # contains a struct.
182 gdb_test "ptype /o struct poi" \
183 [string_to_regexp [multi_line \
184 "/* offset | size */ type = struct poi \{" \
185 "/* 0 | 4 */ int f1;" \
186 "/* XXX 4-byte hole */" \
187 "/* 8 | 40 */ union qwe \{" \
188 "/* 24 */ struct tuv \{" \
189 "/* 8 | 4 */ int a1;" \
190 "/* XXX 4-byte hole */" \
191 "/* 16 | 8 */ signed char *a2;" \
192 "/* 24 | 4 */ int a3;" \
193 "/* XXX 4-byte padding */" \
194 "" \
195 " /* total size (bytes): 24 */" \
196 " \} fff1;" \
197 "/* 40 */ struct xyz \{" \
198 "/* 8 | 4 */ int f1;" \
199 "/* 12 | 1 */ signed char f2;" \
200 "/* XXX 3-byte hole */" \
201 "/* 16 | 8 */ void *f3;" \
202 "/* 24 | 24 */ struct tuv \{" \
203 "/* 24 | 4 */ int a1;" \
204 "/* XXX 4-byte hole */" \
205 "/* 32 | 8 */ signed char *a2;" \
206 "/* 40 | 4 */ int a3;" \
207 "/* XXX 4-byte padding */" \
208 "" \
209 " /* total size (bytes): 24 */" \
210 " \} f4;" \
211 "" \
212 " /* total size (bytes): 40 */" \
213 " \} fff2;" \
214 "/* XXX 32-byte padding */" \
215 "" \
216 " /* total size (bytes): 40 */" \
217 " \} f2;" \
218 "/* 48 | 2 */ uint16_t f3;" \
219 "/* XXX 6-byte hole */" \
220 "/* 56 | 56 */ struct pqr \{" \
221 "/* 56 | 4 */ int ff1;" \
222 "/* XXX 4-byte hole */" \
223 "/* 64 | 40 */ struct xyz \{" \
224 "/* 64 | 4 */ int f1;" \
225 "/* 68 | 1 */ signed char f2;" \
226 "/* XXX 3-byte hole */" \
227 "/* 72 | 8 */ void *f3;" \
228 "/* 80 | 24 */ struct tuv \{" \
229 "/* 80 | 4 */ int a1;" \
230 "/* XXX 4-byte hole */" \
231 "/* 88 | 8 */ signed char *a2;" \
232 "/* 96 | 4 */ int a3;" \
233 "/* XXX 4-byte padding */" \
234 "" \
235 " /* total size (bytes): 24 */" \
236 " \} f4;" \
237 "" \
238 " /* total size (bytes): 40 */" \
239 " \} ff2;" \
240 "/* 104 | 1 */ signed char ff3;" \
241 "/* XXX 7-byte padding */" \
242 "" \
243 " /* total size (bytes): 56 */" \
244 " \} f4;" \
245 "" \
246 " /* total size (bytes): 112 */" \
247 " \}"]]
248
249 # Test printing a struct with several bitfields, laid out in various
250 # ways.
251 #
252 # Because dealing with bitfields and offsets is difficult, it can be
253 # tricky to confirm that the output of this command is accurate. A
254 # nice way to do that is to use GDB's "x" command and print the actual
255 # memory layout of the struct. In order to differentiate between
256 # bitfields and non-bitfield variables, one can assign "-1" to every
257 # bitfield in the struct. An example of the output of "x" using
258 # "struct tyu" is:
259 #
260 # (gdb) x/24xb &e
261 # 0x7fffffffd540: 0xff 0xff 0xff 0x1f 0x00 0x00 0x00 0x00
262 # 0x7fffffffd548: 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
263 # 0x7fffffffd550: 0xff 0x00 0x00 0x00 0x00 0x00 0x00 0x00
264 gdb_test "ptype /o struct tyu" \
265 [string_to_regexp [multi_line \
266 "/* offset | size */ type = struct tyu \{" \
267 "/* 0: 0 | 4 */ int a1 : 1;" \
268 "/* 0: 1 | 4 */ int a2 : 3;" \
269 "/* 0: 4 | 4 */ int a3 : 23;" \
270 "/* 3: 3 | 1 */ signed char a4 : 2;" \
271 "/* XXX 3-bit hole */" \
272 "/* XXX 4-byte hole */" \
273 "/* 8 | 8 */ int64_t a5;" \
274 "/* 16: 0 | 4 */ int a6 : 5;" \
275 "/* 16: 5 | 8 */ int64_t a7 : 3;" \
276 "/* XXX 7-byte padding */" \
277 "" \
278 " /* total size (bytes): 24 */" \
279 " \}"]]
280
281 gdb_test "ptype /o struct asd" \
282 [string_to_regexp [multi_line \
283 "/* offset | size */ type = struct asd \{" \
284 "/* 0 | 32 */ struct asd::jkl \{" \
285 "/* 0 | 8 */ signed char *f1;" \
286 "/* 8 | 8 */ union \{" \
287 "/* 8 */ void *ff1;" \
288 "" \
289 " /* total size (bytes): 8 */" \
290 " \} f2;" \
291 "/* 16 | 8 */ union \{" \
292 "/* 8 */ signed char *ff2;" \
293 "" \
294 " /* total size (bytes): 8 */" \
295 " \} f3;" \
296 "/* 24: 0 | 4 */ int f4 : 5;" \
297 "/* 24: 5 | 4 */ unsigned int f5 : 1;" \
298 "/* XXX 2-bit hole */" \
299 "/* XXX 1-byte hole */" \
300 "/* 26 | 2 */ short f6;" \
301 "/* XXX 4-byte padding */" \
302 "" \
303 " /* total size (bytes): 32 */" \
304 " \} f7;" \
305 "/* 32 | 8 */ unsigned long f8;" \
306 "/* 40 | 8 */ signed char *f9;" \
307 "/* 48: 0 | 4 */ int f10 : 4;" \
308 "/* 48: 4 | 4 */ unsigned int f11 : 1;" \
309 "/* 48: 5 | 4 */ unsigned int f12 : 1;" \
310 "/* 48: 6 | 4 */ unsigned int f13 : 1;" \
311 "/* 48: 7 | 4 */ unsigned int f14 : 1;" \
312 "/* XXX 7-byte hole */" \
313 "/* 56 | 8 */ void *f15;" \
314 "/* 64 | 8 */ void *f16;" \
315 "" \
316 " /* total size (bytes): 72 */" \
317 " \}"]]
318
319 # Test that we don't print any header when issuing a "ptype /o" on a
320 # non-struct, non-union, non-class type.
321 gdb_test "ptype /o int" "int"
322 gdb_test "ptype /o uint8_t" "char"
323
324 # Test that the "whatis" command doesn't print anything related to the
325 # "offsets" feature, even when receiving the "/o" parameter.
326 set test "whatis /o asd"
327 gdb_test_multiple "$test" "$test" {
328 -re "^$test\r\ntype = asd\r\n$gdb_prompt $" {
329 pass $test
330 }
331 }
332
333 # Test that printing a struct with a static member of itself doesn't
334 # get us into an infinite loop.
335 gdb_test "ptype/o static_member" \
336 [string_to_regexp [multi_line \
337 "/* offset | size */ type = struct static_member \{" \
338 " static static_member Empty;" \
339 "\/* 0 | 4 */ int abc;" \
340 "" \
341 " /* total size (bytes): 4 */" \
342 " \}"]]
This page took 0.037532 seconds and 4 git commands to generate.