Commit | Line | Data |
---|---|---|
06d72e16 PA |
1 | /* This testcase is part of GDB, the GNU debugger. |
2 | ||
618f726f | 3 | Copyright 2002-2016 Free Software Foundation, Inc. |
06d72e16 PA |
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 | #include <stdlib.h> | |
19 | #include <string.h> | |
20 | ||
21 | /* Test program partial trace data visualization. */ | |
22 | ||
23 | /* Typedefs. */ | |
24 | ||
25 | typedef struct TEST_STRUCT { | |
26 | char memberc; | |
27 | int memberi; | |
28 | float memberf; | |
29 | double memberd; | |
30 | } test_struct; | |
31 | ||
39d37385 PA |
32 | struct small_struct |
33 | { | |
34 | int member; | |
35 | }; | |
36 | ||
37 | struct small_struct_b : public small_struct | |
38 | { | |
39 | }; | |
40 | ||
06d72e16 PA |
41 | typedef int test_array [4]; |
42 | ||
43 | /* Global variables to be collected. */ | |
44 | ||
45 | char globalc; | |
46 | int globali; | |
47 | float globalf; | |
48 | double globald; | |
49 | test_struct globalstruct; | |
50 | test_struct *globalp; | |
51 | int globalarr[16]; | |
39d37385 PA |
52 | small_struct g_smallstruct; |
53 | small_struct_b g_smallstruct_b; | |
06d72e16 PA |
54 | |
55 | /* Strings. */ | |
56 | ||
57 | const char g_const_string[] = "hello world"; | |
58 | char g_string_unavail[sizeof (g_const_string)]; | |
59 | char g_string_partial[sizeof (g_const_string)]; | |
60 | const char *g_string_p; | |
61 | ||
62 | /* Used to check that <unavailable> is not the same as 0 in array | |
63 | element repetitions. */ | |
64 | ||
65 | struct tuple | |
66 | { | |
67 | int a; | |
68 | int b; | |
69 | }; | |
70 | ||
71 | struct tuple tarray[8]; | |
72 | ||
1b28d0b3 PA |
73 | /* Test for overcollection. GDB used to merge memory ranges to |
74 | collect if they were close enough --- say, collect `a' and 'c' | |
75 | below, and you'd get 'b' as well. This had been presumably done to | |
76 | cater for some target's inefficient trace buffer layout, but it is | |
77 | really not GDB's business to assume how the target manages its | |
78 | buffer. If the target wants to overcollect, that's okay, since it | |
79 | knows what is and what isn't safe to touch (think memory mapped | |
80 | registers), and knows it's buffer layout. | |
81 | ||
82 | The test assumes these three variables are laid out consecutively | |
83 | in memory. Unfortunately, we can't use an array instead, since the | |
84 | agent expression generator does not even do constant folding, | |
85 | meaning that anything that's more complicated than collecting a | |
86 | global will generate an agent expression action to evaluate on the | |
87 | target, instead of a simple "collect memory" action. */ | |
88 | int a; | |
89 | int b; | |
90 | int c; | |
91 | ||
06d72e16 PA |
92 | /* Random tests. */ |
93 | ||
94 | struct StructA | |
95 | { | |
96 | int a, b; | |
97 | int array[10000]; | |
98 | void *ptr; | |
99 | int bitfield:1; | |
100 | }; | |
101 | ||
102 | struct StructB | |
103 | { | |
104 | int d, ef; | |
105 | StructA struct_a; | |
106 | int s:1; | |
107 | static StructA static_struct_a; | |
108 | const char *string; | |
109 | }; | |
110 | ||
111 | /* References. */ | |
112 | ||
113 | int g_int; | |
114 | int &g_ref = g_int; | |
115 | ||
116 | struct StructRef | |
117 | { | |
118 | StructRef (unsigned int val) : ref(d) {} | |
119 | ||
120 | void clear () | |
121 | { | |
122 | d = 0; | |
123 | } | |
124 | ||
125 | unsigned int d; | |
126 | unsigned int &ref; | |
127 | }; | |
128 | ||
129 | struct StructB struct_b; | |
130 | struct StructA StructB::static_struct_a; | |
131 | ||
132 | StructRef g_structref(0x12345678); | |
133 | StructRef *g_structref_p = &g_structref; | |
134 | ||
8af8e3bc PA |
135 | class Base |
136 | { | |
137 | protected: | |
138 | int x; | |
139 | ||
140 | public: | |
141 | Base(void) { x = 2; }; | |
142 | }; | |
143 | ||
144 | class Middle: public virtual Base | |
145 | { | |
146 | protected: | |
147 | int y; | |
148 | ||
149 | public: | |
150 | Middle(void): Base() { y = 3; }; | |
151 | }; | |
152 | ||
153 | class Derived: public virtual Middle { | |
154 | protected: | |
155 | int z; | |
156 | ||
157 | public: | |
158 | Derived(void): Middle() { z = 4; }; | |
159 | }; | |
160 | ||
161 | Derived derived_unavail; | |
162 | Derived derived_partial; | |
163 | Derived derived_whole; | |
164 | ||
ec0a52e1 PA |
165 | struct Virtual { |
166 | int z; | |
167 | ||
168 | virtual ~Virtual() {} | |
169 | }; | |
170 | ||
8af8e3bc PA |
171 | Virtual virtual_partial; |
172 | Virtual *virtualp = &virtual_partial; | |
06d72e16 PA |
173 | |
174 | /* Test functions. */ | |
175 | ||
176 | static void | |
177 | begin () /* called before anything else */ | |
178 | { | |
179 | } | |
180 | ||
181 | static void | |
182 | end () /* called after everything else */ | |
183 | { | |
184 | } | |
185 | ||
8661b11b PA |
186 | /* Test (not) collecting args. */ |
187 | ||
188 | int | |
189 | args_test_func (char argc, | |
190 | int argi, | |
191 | float argf, | |
192 | double argd, | |
193 | test_struct argstruct, | |
194 | int argarray[4]) | |
195 | { | |
196 | int i; | |
197 | ||
198 | i = (int) argc + argi + argf + argd + argstruct.memberi + argarray[1]; | |
199 | ||
200 | return i; | |
201 | } | |
202 | ||
203 | /* Test (not) collecting array args. */ | |
204 | ||
205 | /* Test (not) collecting locals. */ | |
206 | ||
207 | int | |
208 | local_test_func () | |
209 | { | |
210 | char locc = 11; | |
211 | int loci = 12; | |
212 | float locf = 13.3; | |
213 | double locd = 14.4; | |
214 | test_struct locst; | |
215 | int locar[4]; | |
216 | int i; | |
217 | struct localstruct {} locdefst; | |
218 | ||
219 | locst.memberc = 15; | |
220 | locst.memberi = 16; | |
221 | locst.memberf = 17.7; | |
222 | locst.memberd = 18.8; | |
223 | locar[0] = 121; | |
224 | locar[1] = 122; | |
225 | locar[2] = 123; | |
226 | locar[3] = 124; | |
227 | ||
228 | i = /* set local_test_func tracepoint here */ | |
229 | (int) locc + loci + locf + locd + locst.memberi + locar[1]; | |
230 | ||
231 | return i; | |
232 | } | |
233 | ||
234 | /* Test collecting register locals. */ | |
235 | ||
236 | int | |
237 | reglocal_test_func () | |
238 | { | |
239 | register char locc = 11; | |
240 | register int loci = 12; | |
241 | register float locf = 13.3; | |
242 | register double locd = 14.4; | |
243 | register test_struct locst; | |
244 | register int locar[4]; | |
245 | int i; | |
246 | ||
247 | locst.memberc = 15; | |
248 | locst.memberi = 16; | |
249 | locst.memberf = 17.7; | |
250 | locst.memberd = 18.8; | |
251 | locar[0] = 121; | |
252 | locar[1] = 122; | |
253 | locar[2] = 123; | |
254 | locar[3] = 124; | |
255 | ||
256 | i = /* set reglocal_test_func tracepoint here */ | |
257 | (int) locc + loci + locf + locd + locst.memberi + locar[1]; | |
258 | ||
259 | return i; | |
260 | } | |
261 | ||
262 | /* Test collecting static locals. */ | |
263 | ||
264 | int | |
265 | statlocal_test_func () | |
266 | { | |
267 | static char locc; | |
268 | static int loci; | |
269 | static float locf; | |
270 | static double locd; | |
271 | static test_struct locst; | |
272 | static int locar[4]; | |
273 | int i; | |
274 | ||
275 | locc = 11; | |
276 | loci = 12; | |
277 | locf = 13.3; | |
278 | locd = 14.4; | |
279 | locst.memberc = 15; | |
280 | locst.memberi = 16; | |
281 | locst.memberf = 17.7; | |
282 | locst.memberd = 18.8; | |
283 | locar[0] = 121; | |
284 | locar[1] = 122; | |
285 | locar[2] = 123; | |
286 | locar[3] = 124; | |
287 | ||
288 | i = /* set statlocal_test_func tracepoint here */ | |
289 | (int) locc + loci + locf + locd + locst.memberi + locar[1]; | |
290 | ||
291 | /* Set static locals back to zero so collected values are clearly special. */ | |
292 | locc = 0; | |
293 | loci = 0; | |
294 | locf = 0; | |
295 | locd = 0; | |
296 | locst.memberc = 0; | |
297 | locst.memberi = 0; | |
298 | locst.memberf = 0; | |
299 | locst.memberd = 0; | |
300 | locar[0] = 0; | |
301 | locar[1] = 0; | |
302 | locar[2] = 0; | |
303 | locar[3] = 0; | |
304 | ||
305 | return i; | |
306 | } | |
307 | ||
06d72e16 PA |
308 | int |
309 | globals_test_func () | |
310 | { | |
311 | int i = 0; | |
312 | ||
313 | i += globalc + globali + globalf + globald; | |
314 | i += globalstruct.memberc + globalstruct.memberi; | |
315 | i += globalstruct.memberf + globalstruct.memberd; | |
316 | i += globalarr[1]; | |
317 | ||
318 | return i; /* set globals_test_func tracepoint here */ | |
319 | } | |
320 | ||
321 | int | |
322 | main (int argc, char **argv, char **envp) | |
323 | { | |
324 | int i = 0; | |
325 | test_struct mystruct; | |
326 | int myarray[4]; | |
327 | ||
328 | begin (); | |
329 | /* Assign collectable values to global variables. */ | |
330 | globalc = 71; | |
331 | globali = 72; | |
332 | globalf = 73.3; | |
333 | globald = 74.4; | |
334 | globalstruct.memberc = 81; | |
335 | globalstruct.memberi = 82; | |
336 | globalstruct.memberf = 83.3; | |
337 | globalstruct.memberd = 84.4; | |
338 | globalp = &globalstruct; | |
339 | ||
340 | for (i = 0; i < 15; i++) | |
341 | globalarr[i] = i; | |
342 | ||
343 | mystruct.memberc = 101; | |
344 | mystruct.memberi = 102; | |
345 | mystruct.memberf = 103.3; | |
346 | mystruct.memberd = 104.4; | |
347 | myarray[0] = 111; | |
348 | myarray[1] = 112; | |
349 | myarray[2] = 113; | |
350 | myarray[3] = 114; | |
351 | ||
352 | g_int = 123; | |
353 | memset (&struct_b, 0xaa, sizeof struct_b); | |
354 | memset (&struct_b.static_struct_a, 0xaa, sizeof struct_b.static_struct_a); | |
355 | struct_b.string = g_const_string; | |
356 | memcpy (g_string_unavail, g_const_string, sizeof (g_const_string)); | |
357 | memcpy (g_string_partial, g_const_string, sizeof (g_const_string)); | |
358 | g_string_p = g_const_string; | |
1b28d0b3 | 359 | a = 1; b = 2; c = 3; |
06d72e16 PA |
360 | |
361 | /* Call test functions, so they can be traced and data collected. */ | |
362 | i = 0; | |
8661b11b PA |
363 | i += args_test_func (1, 2, 3.3, 4.4, mystruct, myarray); |
364 | i += local_test_func (); | |
365 | i += reglocal_test_func (); | |
366 | i += statlocal_test_func (); | |
06d72e16 PA |
367 | i += globals_test_func (); |
368 | ||
369 | /* Set 'em back to zero, so that the collected values will be | |
370 | distinctly different from the "realtime" (end of test) values. */ | |
371 | ||
372 | globalc = 0; | |
373 | globali = 0; | |
374 | globalf = 0; | |
375 | globald = 0; | |
376 | globalstruct.memberc = 0; | |
377 | globalstruct.memberi = 0; | |
378 | globalstruct.memberf = 0; | |
379 | globalstruct.memberd = 0; | |
380 | globalp = 0; | |
381 | for (i = 0; i < 15; i++) | |
382 | globalarr[i] = 0; | |
383 | ||
384 | memset (&struct_b, 0, sizeof struct_b); | |
385 | memset (&struct_b.static_struct_a, 0, sizeof struct_b.static_struct_a); | |
386 | struct_b.string = NULL; | |
387 | memset (g_string_unavail, 0, sizeof (g_string_unavail)); | |
388 | memset (g_string_partial, 0, sizeof (g_string_partial)); | |
389 | g_string_p = NULL; | |
390 | ||
1b28d0b3 PA |
391 | a = b = c = 0; |
392 | ||
06d72e16 PA |
393 | g_int = 0; |
394 | ||
395 | g_structref.clear (); | |
396 | g_structref_p = NULL; | |
397 | ||
398 | end (); | |
399 | return 0; | |
400 | } |