cxx: adding tests for libunwind
authorReto Achermann <reto.achermann@inf.ethz.ch>
Mon, 19 Aug 2019 16:11:33 +0000 (18:11 +0200)
committerReto Achermann <reto.achermann@inf.ethz.ch>
Tue, 20 Aug 2019 17:43:07 +0000 (19:43 +0200)
Signed-off-by: Reto Achermann <reto.achermann@inf.ethz.ch>

usr/tests/cxx/unwind/CMakeLists.txt [new file with mode: 0644]
usr/tests/cxx/unwind/alignment.pass.cpp [new file with mode: 0644]
usr/tests/cxx/unwind/libunwind_01.pass.cpp [new file with mode: 0644]
usr/tests/cxx/unwind/libunwind_02.pass.cpp [new file with mode: 0644]
usr/tests/cxx/unwind/unw_getcontext.pass.cpp [new file with mode: 0644]

diff --git a/usr/tests/cxx/unwind/CMakeLists.txt b/usr/tests/cxx/unwind/CMakeLists.txt
new file mode 100644 (file)
index 0000000..97917b8
--- /dev/null
@@ -0,0 +1,34 @@
+include(AddLLVM) # for add_lit_testsuite
+macro(pythonize_bool var)
+  if (${var})
+    set(${var} True)
+  else()
+    set(${var} False)
+  endif()
+endmacro()
+
+if (NOT DEFINED LIBCXX_ENABLE_SHARED)
+  set(LIBCXX_ENABLE_SHARED ON)
+endif()
+
+pythonize_bool(LIBUNWIND_BUILD_32_BITS)
+pythonize_bool(LIBCXX_ENABLE_SHARED)
+pythonize_bool(LIBUNWIND_ENABLE_SHARED)
+pythonize_bool(LIBUNWIND_ENABLE_THREADS)
+pythonize_bool(LIBUNWIND_ENABLE_EXCEPTIONS)
+pythonize_bool(LIBUNWIND_BUILD_EXTERNAL_THREAD_LIBRARY)
+set(LIBUNWIND_TARGET_INFO "libcxx.test.target_info.LocalTI" CACHE STRING
+    "TargetInfo to use when setting up test environment.")
+set(LIBUNWIND_EXECUTOR "None" CACHE STRING
+    "Executor to use when running tests.")
+
+set(AUTO_GEN_COMMENT "## Autogenerated by libunwind configuration.\n# Do not edit!")
+configure_file(
+  ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
+  ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg
+  @ONLY)
+
+add_lit_testsuite(check-unwind "Running libunwind tests"
+  ${CMAKE_CURRENT_BINARY_DIR}
+  DEPENDS ${LIBUNWIND_TEST_DEPS}
+  )
diff --git a/usr/tests/cxx/unwind/alignment.pass.cpp b/usr/tests/cxx/unwind/alignment.pass.cpp
new file mode 100644 (file)
index 0000000..1a3ca5a
--- /dev/null
@@ -0,0 +1,29 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// The Itanium ABI requires that _Unwind_Exception objects are "double-word
+// aligned".
+
+#include <unwind.h>
+
+// EHABI  : 8-byte aligned
+// itanium: largest supported alignment for the system
+#if defined(_LIBUNWIND_ARM_EHABI)
+static_assert(alignof(_Unwind_Control_Block) == 8,
+              "_Unwind_Control_Block must be double-word aligned");
+#else
+struct MaxAligned {} __attribute__((__aligned__));
+static_assert(alignof(_Unwind_Exception) == alignof(MaxAligned),
+              "_Unwind_Exception must be maximally aligned");
+#endif
+
+int main()
+{
+}
diff --git a/usr/tests/cxx/unwind/libunwind_01.pass.cpp b/usr/tests/cxx/unwind/libunwind_01.pass.cpp
new file mode 100644 (file)
index 0000000..6957d98
--- /dev/null
@@ -0,0 +1,42 @@
+#include <libunwind.h>
+#include <stdlib.h>
+
+void backtrace(int lower_bound) {
+  unw_context_t context;
+  unw_getcontext(&context);
+
+  unw_cursor_t cursor;
+  unw_init_local(&cursor, &context);
+
+  int n = 0;
+  do {
+    ++n;
+    if (n > 100) {
+      abort();
+    }
+  } while (unw_step(&cursor) > 0);
+
+  if (n < lower_bound) {
+    abort();
+  }
+}
+
+void test1(int i) {
+  backtrace(i);
+}
+
+void test2(int i, int j) {
+  backtrace(i);
+  test1(j);
+}
+
+void test3(int i, int j, int k) {
+  backtrace(i);
+  test2(j, k);
+}
+
+int main() {
+  test1(1);
+  test2(1, 2);
+  test3(1, 2, 3);
+}
diff --git a/usr/tests/cxx/unwind/libunwind_02.pass.cpp b/usr/tests/cxx/unwind/libunwind_02.pass.cpp
new file mode 100644 (file)
index 0000000..a0efd1d
--- /dev/null
@@ -0,0 +1,38 @@
+#include <assert.h>
+#include <stdlib.h>
+#include <unwind.h>
+
+#define EXPECTED_NUM_FRAMES 50
+#define NUM_FRAMES_UPPER_BOUND 100
+
+_Unwind_Reason_Code callback(_Unwind_Context *context, void *cnt) {
+  (void)context;
+  int *i = (int *)cnt;
+  ++*i;
+  if (*i > NUM_FRAMES_UPPER_BOUND) {
+    abort();
+  }
+  return _URC_NO_REASON;
+}
+
+void test_backtrace() {
+  int n = 0;
+  _Unwind_Backtrace(&callback, &n);
+  if (n < EXPECTED_NUM_FRAMES) {
+    abort();
+  }
+}
+
+int test(int i) {
+  if (i == 0) {
+    test_backtrace();
+    return 0;
+  } else {
+    return i + test(i - 1);
+  }
+}
+
+int main() {
+  int total = test(50);
+  assert(total == 1275);
+}
diff --git a/usr/tests/cxx/unwind/unw_getcontext.pass.cpp b/usr/tests/cxx/unwind/unw_getcontext.pass.cpp
new file mode 100644 (file)
index 0000000..b012706
--- /dev/null
@@ -0,0 +1,8 @@
+#include <assert.h>
+#include <libunwind.h>
+
+int main() {
+  unw_context_t context;
+  int ret = unw_getcontext(&context);
+  assert(ret == UNW_ESUCCESS);
+}