summaryrefslogtreecommitdiff
path: root/flang/runtime/stop.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'flang/runtime/stop.cpp')
-rw-r--r--flang/runtime/stop.cpp33
1 files changed, 32 insertions, 1 deletions
diff --git a/flang/runtime/stop.cpp b/flang/runtime/stop.cpp
index cfb36b408402..a7be8a082e02 100644
--- a/flang/runtime/stop.cpp
+++ b/flang/runtime/stop.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "flang/Runtime/stop.h"
+#include "config.h"
#include "environment.h"
#include "file.h"
#include "io-error.h"
@@ -16,6 +17,10 @@
#include <cstdio>
#include <cstdlib>
+#ifdef HAVE_BACKTRACE
+#include BACKTRACE_HEADER
+#endif
+
extern "C" {
static void DescribeIEEESignaledExceptions() {
@@ -152,11 +157,37 @@ void RTNAME(PauseStatementText)(const char *code, std::size_t length) {
std::exit(status);
}
+static void PrintBacktrace() {
+#ifdef HAVE_BACKTRACE
+ // TODO: Need to parse DWARF information to print function line numbers
+ constexpr int MAX_CALL_STACK{999};
+ void *buffer[MAX_CALL_STACK];
+ int nptrs{(int)backtrace(buffer, MAX_CALL_STACK)};
+
+ if (char **symbols{backtrace_symbols(buffer, nptrs)}) {
+ for (int i = 0; i < nptrs; i++) {
+ Fortran::runtime::Terminator{}.PrintCrashArgs("#%d %s\n", i, symbols[i]);
+ }
+ free(symbols);
+ }
+
+#else
+
+ // TODO: Need to implement the version for other platforms.
+ Fortran::runtime::Terminator{}.PrintCrashArgs("backtrace is not supported.");
+
+#endif
+}
+
[[noreturn]] void RTNAME(Abort)() {
- // TODO: Add backtrace call, unless with `-fno-backtrace`.
+#ifdef HAVE_BACKTRACE
+ PrintBacktrace();
+#endif
std::abort();
}
+void FORTRAN_PROCEDURE_NAME(backtrace)() { PrintBacktrace(); }
+
[[noreturn]] void RTNAME(ReportFatalUserError)(
const char *message, const char *source, int line) {
Fortran::runtime::Terminator{source, line}.Crash(message);