Skip to content

Commit e8baa79

Browse files
authoredDec 10, 2024
Backtrace support for flang (#118179)
Fixed build failures in old PRs due to missing files
1 parent e088249 commit e8baa79

File tree

5 files changed

+46
-2
lines changed

5 files changed

+46
-2
lines changed
 

‎flang/docs/Intrinsics.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -705,6 +705,7 @@ MALLOC, FREE
705705

706706
### Library subroutine
707707
```
708+
CALL BACKTRACE()
708709
CALL FDATE(TIME)
709710
CALL GETLOG(USRNAME)
710711
CALL GETENV(NAME [, VALUE, LENGTH, STATUS, TRIM_NAME, ERRMSG ])
@@ -769,7 +770,7 @@ This phase currently supports all the intrinsic procedures listed above but the
769770
| Intrinsic subroutines |MVBITS (elemental), CPU_TIME, DATE_AND_TIME, EVENT_QUERY, EXECUTE_COMMAND_LINE, GET_COMMAND, GET_COMMAND_ARGUMENT, GET_ENVIRONMENT_VARIABLE, MOVE_ALLOC, RANDOM_INIT, RANDOM_NUMBER, RANDOM_SEED, SIGNAL, SLEEP, SYSTEM, SYSTEM_CLOCK |
770771
| Atomic intrinsic subroutines | ATOMIC_ADD |
771772
| Collective intrinsic subroutines | CO_REDUCE |
772-
| Library subroutines | FDATE, GETLOG, GETENV |
773+
| Library subroutines | BACKTRACE, FDATE, GETLOG, GETENV |
773774

774775

775776
### Intrinsic Function Folding

‎flang/include/flang/Runtime/stop.h

+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include "flang/Runtime/c-or-cpp.h"
1313
#include "flang/Runtime/entry-names.h"
14+
#include "flang/Runtime/extensions.h"
1415
#include <stdlib.h>
1516

1617
FORTRAN_EXTERN_C_BEGIN
@@ -29,6 +30,7 @@ NORETURN void RTNAME(ProgramEndStatement)(NO_ARGUMENTS);
2930
// Extensions
3031
NORETURN void RTNAME(Exit)(int status DEFAULT_VALUE(EXIT_SUCCESS));
3132
NORETURN void RTNAME(Abort)(NO_ARGUMENTS);
33+
void FORTRAN_PROCEDURE_NAME(backtrace)(NO_ARGUMENTS);
3234

3335
// Crash with an error message when the program dynamically violates a Fortran
3436
// constraint.

‎flang/runtime/CMakeLists.txt

+5
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,11 @@ if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
5959
)
6060
endif()
6161

62+
# function checks
63+
find_package(Backtrace)
64+
set(HAVE_BACKTRACE ${Backtrace_FOUND})
65+
set(BACKTRACE_HEADER ${Backtrace_HEADER})
66+
6267
include(CheckCXXSymbolExists)
6368
include(CheckCXXSourceCompiles)
6469
check_cxx_symbol_exists(strerror_r string.h HAVE_STRERROR_R)

‎flang/runtime/config.h.cmake

+5
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,9 @@
88
don't. */
99
#cmakedefine01 HAVE_DECL_STRERROR_S
1010

11+
/* Define to 1 if you have the `backtrace' function. */
12+
#cmakedefine HAVE_BACKTRACE ${HAVE_BACKTRACE}
13+
14+
#define BACKTRACE_HEADER <${BACKTRACE_HEADER}>
15+
1116
#endif

‎flang/runtime/stop.cpp

+32-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "flang/Runtime/stop.h"
10+
#include "config.h"
1011
#include "environment.h"
1112
#include "file.h"
1213
#include "io-error.h"
@@ -16,6 +17,10 @@
1617
#include <cstdio>
1718
#include <cstdlib>
1819

20+
#ifdef HAVE_BACKTRACE
21+
#include BACKTRACE_HEADER
22+
#endif
23+
1924
extern "C" {
2025

2126
static void DescribeIEEESignaledExceptions() {
@@ -152,11 +157,37 @@ void RTNAME(PauseStatementText)(const char *code, std::size_t length) {
152157
std::exit(status);
153158
}
154159

160+
static void PrintBacktrace() {
161+
#ifdef HAVE_BACKTRACE
162+
// TODO: Need to parse DWARF information to print function line numbers
163+
constexpr int MAX_CALL_STACK{999};
164+
void *buffer[MAX_CALL_STACK];
165+
int nptrs{backtrace(buffer, MAX_CALL_STACK)};
166+
167+
if (char **symbols{backtrace_symbols(buffer, nptrs)}) {
168+
for (int i = 0; i < nptrs; i++) {
169+
Fortran::runtime::Terminator{}.PrintCrashArgs("#%d %s\n", i, symbols[i]);
170+
}
171+
free(symbols);
172+
}
173+
174+
#else
175+
176+
// TODO: Need to implement the version for other platforms.
177+
Fortran::runtime::Terminator{}.PrintCrashArgs("backtrace is not supported.");
178+
179+
#endif
180+
}
181+
155182
[[noreturn]] void RTNAME(Abort)() {
156-
// TODO: Add backtrace call, unless with `-fno-backtrace`.
183+
#ifdef HAVE_BACKTRACE
184+
PrintBacktrace();
185+
#endif
157186
std::abort();
158187
}
159188

189+
void FORTRAN_PROCEDURE_NAME(backtrace)() { PrintBacktrace(); }
190+
160191
[[noreturn]] void RTNAME(ReportFatalUserError)(
161192
const char *message, const char *source, int line) {
162193
Fortran::runtime::Terminator{source, line}.Crash(message);

0 commit comments

Comments
 (0)
Please sign in to comment.