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
10int ok;
11int verbose;
12
13#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 3)
14void a (int, ...) __attribute__((optimize(0)));
15void b (void) __attribute__((optimize(0)));
16void c (void) __attribute__((optimize(0)));
17#endif
18
19void NOINLINE
20b (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
38void NOINLINE
39c (void)
40{
41    b ();
42}
43
44void NOINLINE
45a (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
66int
67main (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