1/* This testcase is part of GDB, the GNU debugger. 2 3 Copyright 2002-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#include <stdlib.h> 19#include <string.h> 20 21/* Test program partial trace data visualization. */ 22 23/* Typedefs. */ 24 25typedef struct TEST_STRUCT { 26 char memberc; 27 int memberi; 28 float memberf; 29 double memberd; 30} test_struct; 31 32struct small_struct 33{ 34 int member; 35}; 36 37struct small_struct_b : public small_struct 38{ 39}; 40 41typedef int test_array [4]; 42 43/* Global variables to be collected. */ 44 45char globalc; 46int globali; 47float globalf; 48double globald; 49test_struct globalstruct; 50test_struct *globalp; 51int globalarr[16]; 52small_struct g_smallstruct; 53small_struct_b g_smallstruct_b; 54 55/* Strings. */ 56 57const char g_const_string[] = "hello world"; 58char g_string_unavail[sizeof (g_const_string)]; 59char g_string_partial[sizeof (g_const_string)]; 60const char *g_string_p; 61 62/* Used to check that <unavailable> is not the same as 0 in array 63 element repetitions. */ 64 65struct tuple 66{ 67 int a; 68 int b; 69}; 70 71struct tuple tarray[8]; 72 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. */ 88int a; 89int b; 90int c; 91 92/* Random tests. */ 93 94struct StructA 95{ 96 int a, b; 97 int array[10000]; 98 void *ptr; 99 int bitfield:1; 100}; 101 102struct 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 113int g_int; 114int &g_ref = g_int; 115 116struct 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 129struct StructB struct_b; 130struct StructA StructB::static_struct_a; 131 132StructRef g_structref(0x12345678); 133StructRef *g_structref_p = &g_structref; 134 135class Base 136{ 137protected: 138 int x; 139 140public: 141 Base(void) { x = 2; }; 142}; 143 144class Middle: public virtual Base 145{ 146protected: 147 int y; 148 149public: 150 Middle(void): Base() { y = 3; }; 151}; 152 153class Derived: public virtual Middle { 154protected: 155 int z; 156 157public: 158 Derived(void): Middle() { z = 4; }; 159}; 160 161Derived derived_unavail; 162Derived derived_partial; 163Derived derived_whole; 164 165struct Virtual { 166 int z; 167 168 virtual ~Virtual() {} 169}; 170 171Virtual virtual_partial; 172Virtual *virtualp = &virtual_partial; 173 174/* Test functions. */ 175 176static void 177begin () /* called before anything else */ 178{ 179} 180 181static void 182end () /* called after everything else */ 183{ 184} 185 186/* Test (not) collecting args. */ 187 188int 189args_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 207int 208local_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 236int 237reglocal_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 264int 265statlocal_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 308int 309globals_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 321int 322main (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; 359 a = 1; b = 2; c = 3; 360 361 /* Call test functions, so they can be traced and data collected. */ 362 i = 0; 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 (); 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 391 a = b = c = 0; 392 393 g_int = 0; 394 395 g_structref.clear (); 396 g_structref_p = NULL; 397 398 end (); 399 return 0; 400} 401