[libunwind] Support for leaf function unwinding.
Unwinding leaf function is useful in cases when the backtrace finds a
leaf function for example when it caused a signal.
This patch also add the support for the DW_CFA_undefined because it marks
the end of the frames.
Ryan Prichard provided code for the tests.
Reviewed By: #libunwind, mstorsjo
Differential Revision: https://reviews.llvm.org/D83573
Reland with limit the test to the x86_64-linux target.
Cr-Mirrored-From: https://chromium.googlesource.com/external/github.com/llvm/llvm-project
Cr-Mirrored-Commit: 22b615a96593f13109a27cabfd1764ec4f558c7a
diff --git a/test/unwind_leaffunction.pass.cpp b/test/unwind_leaffunction.pass.cpp
new file mode 100644
index 0000000..8e4fcbe
--- /dev/null
+++ b/test/unwind_leaffunction.pass.cpp
@@ -0,0 +1,51 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// Ensure that leaf function can be unwund.
+// REQUIRES: x86_64-linux
+
+#include <assert.h>
+#include <dlfcn.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <unwind.h>
+
+_Unwind_Reason_Code frame_handler(struct _Unwind_Context* ctx, void* arg) {
+ (void)arg;
+ Dl_info info = { 0, 0, 0, 0 };
+ assert(dladdr((void*)_Unwind_GetIP(ctx), &info));
+
+ // Unwind util the main is reached, above frames deeped on the platfrom and architecture.
+ if(info.dli_sname && !strcmp("main", info.dli_sname)) {
+ _Exit(0);
+ }
+ return _URC_NO_REASON;
+}
+
+void signal_handler(int signum) {
+ (void)signum;
+ _Unwind_Backtrace(frame_handler, NULL);
+ _Exit(-1);
+}
+
+int* faultyPointer = NULL;
+
+__attribute__((noinline)) void crashing_leaf_func(void) {
+ *faultyPointer = 0;
+}
+
+int main() {
+ signal(SIGSEGV, signal_handler);
+ crashing_leaf_func();
+ return -2;
+}
\ No newline at end of file