diff options
Diffstat (limited to 'tests/Ltest-varargs.c')
-rw-r--r-- | tests/Ltest-varargs.c | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/tests/Ltest-varargs.c b/tests/Ltest-varargs.c new file mode 100644 index 00000000..603fb57b --- /dev/null +++ b/tests/Ltest-varargs.c @@ -0,0 +1,82 @@ +#define UNW_LOCAL_ONLY +#include <libunwind.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +int ok; +int verbose; + +#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 3) +void a (int, ...) __attribute__((noinline, optimize(0))); +void b (void) __attribute__((noinline, optimize(0))); +void c (void) __attribute__((noinline, optimize(0))); +#endif + +void +b (void) +{ + void *v[20]; + int i, n; + + n = unw_backtrace(v, 20); + + /* Check that the number of addresses given by unw_backtrace() looks + * reasonable. If the compiler inlined everything, then this check will also + * break. */ + if (n >= 7) + ok = 1; + + if (verbose) + for (i = 0; i < n; ++i) + printf ("[%d] %p\n", i, v[i]); +} + +void +c (void) +{ + b (); +} + +void +a (int d, ...) +{ + switch (d) + { + case 5: + a (4, 2,4); + break; + case 4: + a (3, 1,3,5); + break; + case 3: + a (2, 11, 13, 17, 23); + break; + case 2: + a (1); + break; + case 1: + c (); + } +} + +int +main (int argc, char **argv __attribute__((unused))) +{ + if (argc > 1) + verbose = 1; + + a (5, 3, 4, 5, 6); + + if (!ok) + { + fprintf (stderr, "FAILURE: expected deeper backtrace.\n"); + return 1; + } + + if (verbose) + printf ("SUCCESS.\n"); + + return 0; +} |