1 #define UNW_LOCAL_ONLY 2 #include <libunwind.h> 3 #include "compiler.h" 4 5 #include <stdarg.h> 6 #include <stdio.h> 7 #include <stdlib.h> 8 #include <unistd.h> 9 10 int ok; 11 int verbose; 12 13 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 3) 14 void a (int, ...) __attribute__((optimize(0))); 15 void b (void) __attribute__((optimize(0))); 16 void c (void) __attribute__((optimize(0))); 17 #endif 18 19 void NOINLINE 20 b (void) 21 { 22 void *v[20]; 23 int i, n; 24 25 n = unw_backtrace(v, 20); 26 27 /* Check that the number of addresses given by unw_backtrace() looks 28 * reasonable. If the compiler inlined everything, then this check will also 29 * break. */ 30 if (n >= 7) 31 ok = 1; 32 33 if (verbose) 34 for (i = 0; i < n; ++i) 35 printf ("[%d] %p\n", i, v[i]); 36 } 37 38 void NOINLINE 39 c (void) 40 { 41 b (); 42 } 43 44 void NOINLINE 45 a (int d, ...) 46 { 47 switch (d) 48 { 49 case 5: 50 a (4, 2,4); 51 break; 52 case 4: 53 a (3, 1,3,5); 54 break; 55 case 3: 56 a (2, 11, 13, 17, 23); 57 break; 58 case 2: 59 a (1); 60 break; 61 case 1: 62 c (); 63 } 64 } 65 66 int 67 main (int argc, char **argv UNUSED) 68 { 69 if (argc > 1) 70 verbose = 1; 71 72 a (5, 3, 4, 5, 6); 73 74 if (!ok) 75 { 76 fprintf (stderr, "FAILURE: expected deeper backtrace.\n"); 77 return 1; 78 } 79 80 if (verbose) 81 printf ("SUCCESS.\n"); 82 83 return 0; 84 } 85