|
14 | 14 | //
|
15 | 15 | //===----------------------------------------------------------------------===//
|
16 | 16 |
|
17 |
| -#if defined(__CYGWIN__) || defined(__ANDROID__) || defined(__HAIKU__) |
| 17 | +#if defined(__CYGWIN__) || defined(__HAIKU__) |
18 | 18 | #define SWIFT_SUPPORTS_BACKTRACE_REPORTING 0
|
19 | 19 | #else
|
20 | 20 | #define SWIFT_SUPPORTS_BACKTRACE_REPORTING 1
|
|
58 | 58 | #include <android/log.h>
|
59 | 59 | #endif
|
60 | 60 |
|
| 61 | +#if defined(__ELF__) |
| 62 | +#include <unwind.h> |
| 63 | +#endif |
| 64 | + |
61 | 65 | namespace FatalErrorFlags {
|
62 | 66 | enum: uint32_t {
|
63 | 67 | ReportBacktrace = 1 << 0
|
@@ -188,13 +192,46 @@ void swift::dumpStackTraceEntry(unsigned index, void *framePC,
|
188 | 192 | #endif
|
189 | 193 | }
|
190 | 194 |
|
| 195 | +#if defined(__ELF__) |
| 196 | +struct UnwindState { |
| 197 | + void **current; |
| 198 | + void **end; |
| 199 | +}; |
| 200 | + |
| 201 | +static _Unwind_Reason_Code SwiftUnwindFrame(struct _Unwind_Context *context, void *arg) { |
| 202 | + struct UnwindState *state = static_cast<struct UnwindState *>(arg); |
| 203 | + if (state->current == state->end) { |
| 204 | + return _URC_END_OF_STACK; |
| 205 | + } |
| 206 | + |
| 207 | + uintptr_t pc; |
| 208 | +#if defined(__arm__) |
| 209 | + // ARM r15 is PC. UNW_REG_PC is *not* the same value, and using that will |
| 210 | + // result in abnormal behaviour. |
| 211 | + _Unwind_VRS_Get(context, _UVRSC_CORE, 15, _UVRSD_UINT32, &pc); |
| 212 | + // Clear the ISA bit during the reporting. |
| 213 | + pc &= ~(uintptr_t)0x1; |
| 214 | +#else |
| 215 | + pc = _Unwind_GetIP(context); |
| 216 | +#endif |
| 217 | + if (pc) { |
| 218 | + *state->current++ = reinterpret_cast<void *>(pc); |
| 219 | + } |
| 220 | + return _URC_NO_REASON; |
| 221 | +} |
| 222 | +#endif |
| 223 | + |
191 | 224 | LLVM_ATTRIBUTE_NOINLINE
|
192 | 225 | void swift::printCurrentBacktrace(unsigned framesToSkip) {
|
193 | 226 | #if SWIFT_SUPPORTS_BACKTRACE_REPORTING
|
194 | 227 | constexpr unsigned maxSupportedStackDepth = 128;
|
195 | 228 | void *addrs[maxSupportedStackDepth];
|
196 | 229 | #if defined(_WIN32)
|
197 | 230 | int symbolCount = CaptureStackBackTrace(0, maxSupportedStackDepth, addrs, NULL);
|
| 231 | +#elif defined(__ELF__) |
| 232 | + struct UnwindState state = {&addrs[0], &addrs[maxSupportedStackDepth]}; |
| 233 | + _Unwind_Backtrace(SwiftUnwindFrame, &state); |
| 234 | + int symbolCount = state.current - addrs; |
198 | 235 | #else
|
199 | 236 | int symbolCount = backtrace(addrs, maxSupportedStackDepth);
|
200 | 237 | #endif
|
|
0 commit comments