[flang-commits] [flang] Backtrace support for flang (PR #118179)
via flang-commits
flang-commits at lists.llvm.org
Sat Nov 30 08:17:11 PST 2024
https://github.com/dty2 created https://github.com/llvm/llvm-project/pull/118179
Fixed build failures in old PRs due to missing files
>From 2d5d3107444d244cf5fa2c75cb69000e3c6ca081 Mon Sep 17 00:00:00 2001
From: hunter <284050500 at qq.com>
Date: Tue, 26 Nov 2024 02:18:10 +0800
Subject: [PATCH 1/6] [flang]Add new intrinsic function backtrace and complete
the TODO of abort
---
.../flang/Optimizer/Builder/IntrinsicCall.h | 1 +
.../flang/Optimizer/Builder/Runtime/Stop.h | 3 +++
flang/include/flang/Runtime/stop.h | 1 +
flang/lib/Evaluate/intrinsics.cpp | 1 +
flang/lib/Optimizer/Builder/IntrinsicCall.cpp | 7 +++++++
flang/lib/Optimizer/Builder/Runtime/Stop.cpp | 7 +++++++
flang/runtime/stop.cpp | 21 ++++++++++++++++++-
flang/test/Lower/Intrinsics/backtrace.f90 | 10 +++++++++
8 files changed, 50 insertions(+), 1 deletion(-)
create mode 100644 flang/test/Lower/Intrinsics/backtrace.f90
diff --git a/flang/include/flang/Optimizer/Builder/IntrinsicCall.h b/flang/include/flang/Optimizer/Builder/IntrinsicCall.h
index e83d1a42e34133..7f4b9ebf1d1c21 100644
--- a/flang/include/flang/Optimizer/Builder/IntrinsicCall.h
+++ b/flang/include/flang/Optimizer/Builder/IntrinsicCall.h
@@ -196,6 +196,7 @@ struct IntrinsicLibrary {
fir::ExtendedValue genAssociated(mlir::Type,
llvm::ArrayRef<fir::ExtendedValue>);
mlir::Value genAtand(mlir::Type, llvm::ArrayRef<mlir::Value>);
+ void genBacktrace(llvm::ArrayRef<fir::ExtendedValue>);
fir::ExtendedValue genBesselJn(mlir::Type,
llvm::ArrayRef<fir::ExtendedValue>);
fir::ExtendedValue genBesselYn(mlir::Type,
diff --git a/flang/include/flang/Optimizer/Builder/Runtime/Stop.h b/flang/include/flang/Optimizer/Builder/Runtime/Stop.h
index 6f764badf6f3a8..be73cffff021e3 100644
--- a/flang/include/flang/Optimizer/Builder/Runtime/Stop.h
+++ b/flang/include/flang/Optimizer/Builder/Runtime/Stop.h
@@ -30,6 +30,9 @@ void genExit(fir::FirOpBuilder &, mlir::Location, mlir::Value status);
/// Generate call to ABORT intrinsic runtime routine.
void genAbort(fir::FirOpBuilder &, mlir::Location);
+/// Generate call to BACKTRACE intrinsic runtime routine.
+void genBacktrace(fir::FirOpBuilder &builder, mlir::Location loc);
+
/// Generate call to crash the program with an error message when detecting
/// an invalid situation at runtime.
void genReportFatalUserError(fir::FirOpBuilder &, mlir::Location,
diff --git a/flang/include/flang/Runtime/stop.h b/flang/include/flang/Runtime/stop.h
index f7c4ffe7403e8e..d442f72bfe1fa4 100644
--- a/flang/include/flang/Runtime/stop.h
+++ b/flang/include/flang/Runtime/stop.h
@@ -29,6 +29,7 @@ NORETURN void RTNAME(ProgramEndStatement)(NO_ARGUMENTS);
// Extensions
NORETURN void RTNAME(Exit)(int status DEFAULT_VALUE(EXIT_SUCCESS));
NORETURN void RTNAME(Abort)(NO_ARGUMENTS);
+void RTNAME(Backtrace)(NO_ARGUMENTS);
// Crash with an error message when the program dynamically violates a Fortran
// constraint.
diff --git a/flang/lib/Evaluate/intrinsics.cpp b/flang/lib/Evaluate/intrinsics.cpp
index 1e27c0ae4216c5..599a7d0124b800 100644
--- a/flang/lib/Evaluate/intrinsics.cpp
+++ b/flang/lib/Evaluate/intrinsics.cpp
@@ -1333,6 +1333,7 @@ static const IntrinsicInterface intrinsicSubroutine[]{
{"stat", AnyInt, Rank::scalar, Optionality::optional,
common::Intent::Out}},
{}, Rank::elemental, IntrinsicClass::atomicSubroutine},
+ {"backtrace", {}, {}, Rank::elemental, IntrinsicClass::pureSubroutine},
{"co_broadcast",
{{"a", AnyData, Rank::anyOrAssumedRank, Optionality::required,
common::Intent::InOut},
diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
index a2b327f45c6939..c748c6583a5ce9 100644
--- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
+++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
@@ -150,6 +150,7 @@ static constexpr IntrinsicHandler handlers[]{
{"atan2pi", &I::genAtanpi},
{"atand", &I::genAtand},
{"atanpi", &I::genAtanpi},
+ {"backtrace", &I::genBacktrace},
{"bessel_jn",
&I::genBesselJn,
{{{"n1", asValue}, {"n2", asValue}, {"x", asValue}}},
@@ -2681,6 +2682,12 @@ IntrinsicLibrary::genBesselJn(mlir::Type resultType,
}
}
+// Backtrace
+void IntrinsicLibrary::genBacktrace(llvm::ArrayRef<fir::ExtendedValue> args) {
+ assert(args.size() == 0);
+ fir::runtime::genBacktrace(builder, loc);
+}
+
// BESSEL_YN
fir::ExtendedValue
IntrinsicLibrary::genBesselYn(mlir::Type resultType,
diff --git a/flang/lib/Optimizer/Builder/Runtime/Stop.cpp b/flang/lib/Optimizer/Builder/Runtime/Stop.cpp
index 411181cc6dd1ca..541e5f3b5d11a8 100644
--- a/flang/lib/Optimizer/Builder/Runtime/Stop.cpp
+++ b/flang/lib/Optimizer/Builder/Runtime/Stop.cpp
@@ -28,6 +28,13 @@ void fir::runtime::genAbort(fir::FirOpBuilder &builder, mlir::Location loc) {
builder.create<fir::CallOp>(loc, abortFunc, std::nullopt);
}
+void fir::runtime::genBacktrace(fir::FirOpBuilder &builder,
+ mlir::Location loc) {
+ mlir::func::FuncOp backtraceFunc =
+ fir::runtime::getRuntimeFunc<mkRTKey(Backtrace)>(loc, builder);
+ builder.create<fir::CallOp>(loc, backtraceFunc, std::nullopt);
+}
+
void fir::runtime::genReportFatalUserError(fir::FirOpBuilder &builder,
mlir::Location loc,
llvm::StringRef message) {
diff --git a/flang/runtime/stop.cpp b/flang/runtime/stop.cpp
index cfb36b40840200..57209dc37befa7 100644
--- a/flang/runtime/stop.cpp
+++ b/flang/runtime/stop.cpp
@@ -15,6 +15,7 @@
#include <cfenv>
#include <cstdio>
#include <cstdlib>
+#include <execinfo.h>
extern "C" {
@@ -152,11 +153,29 @@ void RTNAME(PauseStatementText)(const char *code, std::size_t length) {
std::exit(status);
}
+static void PrintBacktrace() {
+ // TODO: Need to parse DWARF information to print function line numbers
+ const int MAX_CALL_STACK = 999;
+ void *buffer[MAX_CALL_STACK];
+ int nptrs = backtrace(buffer, MAX_CALL_STACK);
+ char **symbols = backtrace_symbols(buffer, nptrs);
+ if (symbols == nullptr) {
+ Fortran::runtime::Terminator{}.Crash("no symbols");
+ std::exit(EXIT_FAILURE);
+ }
+ for (int i = 0; i < nptrs; i++) {
+ Fortran::runtime::Terminator{}.PrintCrashArgs("#%d %s\n", i, symbols[i]);
+ }
+ free(symbols);
+}
+
[[noreturn]] void RTNAME(Abort)() {
- // TODO: Add backtrace call, unless with `-fno-backtrace`.
+ PrintBacktrace();
std::abort();
}
+void RTNAME(Backtrace)() { PrintBacktrace(); }
+
[[noreturn]] void RTNAME(ReportFatalUserError)(
const char *message, const char *source, int line) {
Fortran::runtime::Terminator{source, line}.Crash(message);
diff --git a/flang/test/Lower/Intrinsics/backtrace.f90 b/flang/test/Lower/Intrinsics/backtrace.f90
new file mode 100644
index 00000000000000..9d5e7b4965baff
--- /dev/null
+++ b/flang/test/Lower/Intrinsics/backtrace.f90
@@ -0,0 +1,10 @@
+! RUN: bbc -emit-fir %s -o - | FileCheck %s
+
+! CHECK-LABEL: func.func @_QPbacktrace_test() {
+! CHECK: %[[VAL_0:.*]] = fir.call @_FortranABacktrace() {{.*}}: () -> none
+! CHECK: return
+! CHECK: }
+
+subroutine backtrace_test()
+ call backtrace
+end subroutine
>From 6b5719316f5638a93424de60289d26a2120edd19 Mon Sep 17 00:00:00 2001
From: hunter <284050500 at qq.com>
Date: Tue, 26 Nov 2024 03:50:31 +0800
Subject: [PATCH 2/6] commit some suggestions
---
.../Optimizer/Builder/Runtime/Intrinsics.cpp | 1 +
flang/runtime/stop.cpp | 19 ++++++++++++++++---
2 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/flang/lib/Optimizer/Builder/Runtime/Intrinsics.cpp b/flang/lib/Optimizer/Builder/Runtime/Intrinsics.cpp
index ded9579f2c1df0..166c4ef650bb48 100644
--- a/flang/lib/Optimizer/Builder/Runtime/Intrinsics.cpp
+++ b/flang/lib/Optimizer/Builder/Runtime/Intrinsics.cpp
@@ -20,6 +20,7 @@
#include "flang/Runtime/time-intrinsic.h"
#include "flang/Semantics/tools.h"
#include "llvm/Support/Debug.h"
+
#include <optional>
#include <signal.h>
diff --git a/flang/runtime/stop.cpp b/flang/runtime/stop.cpp
index 57209dc37befa7..c3ec41be98b7f3 100644
--- a/flang/runtime/stop.cpp
+++ b/flang/runtime/stop.cpp
@@ -15,7 +15,10 @@
#include <cfenv>
#include <cstdio>
#include <cstdlib>
+
+#ifdef __linux__
#include <execinfo.h>
+#endif
extern "C" {
@@ -154,19 +157,29 @@ void RTNAME(PauseStatementText)(const char *code, std::size_t length) {
}
static void PrintBacktrace() {
+#ifdef __linux__
// TODO: Need to parse DWARF information to print function line numbers
- const int MAX_CALL_STACK = 999;
+ constexpr int MAX_CALL_STACK{999};
void *buffer[MAX_CALL_STACK];
- int nptrs = backtrace(buffer, MAX_CALL_STACK);
- char **symbols = backtrace_symbols(buffer, nptrs);
+ int nptrs{backtrace(buffer, MAX_CALL_STACK)};
+ char **symbols{backtrace_symbols(buffer, nptrs)};
+
if (symbols == nullptr) {
Fortran::runtime::Terminator{}.Crash("no symbols");
std::exit(EXIT_FAILURE);
}
+
for (int i = 0; i < nptrs; i++) {
Fortran::runtime::Terminator{}.PrintCrashArgs("#%d %s\n", i, symbols[i]);
}
+
free(symbols);
+
+#else
+
+ // TODO: Windows platform implemention
+
+#endif
}
[[noreturn]] void RTNAME(Abort)() {
>From d28136f18fdcc953908a40a0c10d0687dc659ce4 Mon Sep 17 00:00:00 2001
From: hunter <284050500 at qq.com>
Date: Wed, 27 Nov 2024 01:44:45 +0800
Subject: [PATCH 3/6] [flang]Import the header file config.h in
flang/runtime/stop.cpp and delete std::exit in PrintBacktrace
---
.../Optimizer/Builder/Runtime/Intrinsics.cpp | 1 -
flang/runtime/stop.cpp | 24 ++++++++-----------
2 files changed, 10 insertions(+), 15 deletions(-)
diff --git a/flang/lib/Optimizer/Builder/Runtime/Intrinsics.cpp b/flang/lib/Optimizer/Builder/Runtime/Intrinsics.cpp
index 166c4ef650bb48..ded9579f2c1df0 100644
--- a/flang/lib/Optimizer/Builder/Runtime/Intrinsics.cpp
+++ b/flang/lib/Optimizer/Builder/Runtime/Intrinsics.cpp
@@ -20,7 +20,6 @@
#include "flang/Runtime/time-intrinsic.h"
#include "flang/Semantics/tools.h"
#include "llvm/Support/Debug.h"
-
#include <optional>
#include <signal.h>
diff --git a/flang/runtime/stop.cpp b/flang/runtime/stop.cpp
index c3ec41be98b7f3..639acc1dd43189 100644
--- a/flang/runtime/stop.cpp
+++ b/flang/runtime/stop.cpp
@@ -16,8 +16,9 @@
#include <cstdio>
#include <cstdlib>
-#ifdef __linux__
-#include <execinfo.h>
+#include "llvm/Config/config.h"
+#ifdef HAVE_BACKTRACE
+#include BACKTRACE_HEADER
#endif
extern "C" {
@@ -157,27 +158,22 @@ void RTNAME(PauseStatementText)(const char *code, std::size_t length) {
}
static void PrintBacktrace() {
-#ifdef __linux__
+#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{backtrace(buffer, MAX_CALL_STACK)};
- char **symbols{backtrace_symbols(buffer, nptrs)};
- if (symbols == nullptr) {
- Fortran::runtime::Terminator{}.Crash("no symbols");
- std::exit(EXIT_FAILURE);
- }
-
- for (int i = 0; i < nptrs; i++) {
- Fortran::runtime::Terminator{}.PrintCrashArgs("#%d %s\n", i, symbols[i]);
+ 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);
}
- free(symbols);
-
#else
- // TODO: Windows platform implemention
+ // TODO: Windows platform implementation
#endif
}
>From ca2ceb5a5b47b45a9ae05286430507ba5372eef7 Mon Sep 17 00:00:00 2001
From: hunter <284050500 at qq.com>
Date: Wed, 27 Nov 2024 10:30:46 +0800
Subject: [PATCH 4/6] [flang]Handle the case when a backtrace is not available
---
flang/runtime/stop.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/flang/runtime/stop.cpp b/flang/runtime/stop.cpp
index 639acc1dd43189..1a1af6425009a5 100644
--- a/flang/runtime/stop.cpp
+++ b/flang/runtime/stop.cpp
@@ -173,7 +173,8 @@ static void PrintBacktrace() {
#else
- // TODO: Windows platform implementation
+ // TODO: Need to implement the version for other platforms.
+ Fortran::runtime::Terminator{}.PrintCrashArgs("Handle the case when a backtrace is not available");
#endif
}
>From c2e4ccaf6457e8a46bc765c29c8b49edb3682fd0 Mon Sep 17 00:00:00 2001
From: hunter <284050500 at qq.com>
Date: Thu, 28 Nov 2024 02:06:50 +0800
Subject: [PATCH 5/6] [flang]update format
---
flang/runtime/stop.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/flang/runtime/stop.cpp b/flang/runtime/stop.cpp
index 1a1af6425009a5..17d0ca661d9e84 100644
--- a/flang/runtime/stop.cpp
+++ b/flang/runtime/stop.cpp
@@ -174,7 +174,8 @@ static void PrintBacktrace() {
#else
// TODO: Need to implement the version for other platforms.
- Fortran::runtime::Terminator{}.PrintCrashArgs("Handle the case when a backtrace is not available");
+ Fortran::runtime::Terminator{}.PrintCrashArgs(
+ "Handle the case when a backtrace is not available");
#endif
}
>From 30e5858e72c7a21ff0ac5dc9358bc5b270fe970b Mon Sep 17 00:00:00 2001
From: hunter <284050500 at qq.com>
Date: Sun, 1 Dec 2024 00:08:39 +0800
Subject: [PATCH 6/6] [flang]Fix missing file issue
---
flang/lib/Evaluate/intrinsics.cpp | 2 +-
flang/runtime/config.h.cmake | 5 +++++
flang/runtime/stop.cpp | 4 ++--
3 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/flang/lib/Evaluate/intrinsics.cpp b/flang/lib/Evaluate/intrinsics.cpp
index 87ce6ed3396676..1f30e339067fd6 100644
--- a/flang/lib/Evaluate/intrinsics.cpp
+++ b/flang/lib/Evaluate/intrinsics.cpp
@@ -1336,7 +1336,7 @@ static const IntrinsicInterface intrinsicSubroutine[]{
{"stat", AnyInt, Rank::scalar, Optionality::optional,
common::Intent::Out}},
{}, Rank::elemental, IntrinsicClass::atomicSubroutine},
- {"backtrace", {}, {}, Rank::elemental, IntrinsicClass::pureSubroutine},
+ {"backtrace", {}, {}, Rank::elemental, IntrinsicClass::impureSubroutine},
{"co_broadcast",
{{"a", AnyData, Rank::anyOrAssumedRank, Optionality::required,
common::Intent::InOut},
diff --git a/flang/runtime/config.h.cmake b/flang/runtime/config.h.cmake
index 0a1d1394b9bc49..432ba5cc32abe3 100644
--- a/flang/runtime/config.h.cmake
+++ b/flang/runtime/config.h.cmake
@@ -8,4 +8,9 @@
don't. */
#cmakedefine01 HAVE_DECL_STRERROR_S
+/* Define to 1 if you have the `backtrace' function. */
+#cmakedefine01 HAVE_BACKTRACE
+
+#define BACKTRACE_HEADER <execinfo.h>
+
#endif
diff --git a/flang/runtime/stop.cpp b/flang/runtime/stop.cpp
index 17d0ca661d9e84..7b65833eb4337c 100644
--- a/flang/runtime/stop.cpp
+++ b/flang/runtime/stop.cpp
@@ -12,11 +12,11 @@
#include "io-error.h"
#include "terminator.h"
#include "unit.h"
+#include "config.h"
#include <cfenv>
#include <cstdio>
#include <cstdlib>
-#include "llvm/Config/config.h"
#ifdef HAVE_BACKTRACE
#include BACKTRACE_HEADER
#endif
@@ -175,7 +175,7 @@ static void PrintBacktrace() {
// TODO: Need to implement the version for other platforms.
Fortran::runtime::Terminator{}.PrintCrashArgs(
- "Handle the case when a backtrace is not available");
+ "Handle the case when a backtrace is not available\n");
#endif
}
More information about the flang-commits
mailing list