1 # This testcase is part of GDB
, the GNU debugger.
3 # Copyright
2017-2019 Free Software Foundation
, Inc.
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.
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.
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
/>.
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.
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"
30 if { [prepare_for_testing "failed to prepare" $testfile $srcfile \
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 \{" \
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;" \
52 " /* total size (bytes): 8 */" \
54 "/* 48 | 2 */ my_int_type field9;" \
55 "/* XXX 6-byte padding */" \
57 " /* total size (bytes): 56 */" \
61 gdb_test "ptype /oTM struct abc" \
62 [string_to_regexp [multi_line \
63 "/* offset | size */ type = struct abc \{" \
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;" \
77 " /* total size (bytes): 8 */" \
79 "/* 48 | 2 */ my_int_type field9;" \
84 " typedef short my_int_type;" \
85 "/* XXX 6-byte padding */" \
87 " /* total size (bytes): 56 */" \
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 \{" \
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;" \
107 " /* total size (bytes): 8 */" \
109 "/* 48 | 2 */ my_int_type field9;" \
110 "/* XXX 6-byte padding */" \
112 " /* total size (bytes): 56 */" \
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 */" \
133 " /* total size (bytes): 24 */" \
136 " /* total size (bytes): 40 */" \
138 "/* 48 | 1 */ signed char ff3;" \
139 "/* XXX 7-byte padding */" \
141 " /* total size (bytes): 56 */" \
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 */" \
157 " /* total size (bytes): 24 */" \
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 */" \
171 " /* total size (bytes): 24 */" \
174 " /* total size (bytes): 40 */" \
177 " /* total size (bytes): 40 */" \
180 # Test printing a struct that contains a union, and that also
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 */" \
195 " /* total size (bytes): 24 */" \
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 */" \
209 " /* total size (bytes): 24 */" \
212 " /* total size (bytes): 40 */" \
214 "/* XXX 32-byte padding */" \
216 " /* total size (bytes): 40 */" \
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 */" \
235 " /* total size (bytes): 24 */" \
238 " /* total size (bytes): 40 */" \
240 "/* 104 | 1 */ signed char ff3;" \
241 "/* XXX 7-byte padding */" \
243 " /* total size (bytes): 56 */" \
246 " /* total size (bytes): 112 */" \
249 # Test printing a struct with several bitfields, laid out in various
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
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 */" \
278 " /* total size (bytes): 24 */" \
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;" \
289 " /* total size (bytes): 8 */" \
291 "/* 16 | 8 */ union \{" \
292 "/* 8 */ signed char *ff2;" \
294 " /* total size (bytes): 8 */" \
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 */" \
303 " /* total size (bytes): 32 */" \
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;" \
316 " /* total size (bytes): 72 */" \
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"
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 $" {
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;" \
341 " /* total size (bytes): 4 */" \