summaryrefslogtreecommitdiff
path: root/tests/Ltest-varargs.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/Ltest-varargs.c')
-rw-r--r--tests/Ltest-varargs.c82
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;
+}