Skip to content

Commit ad91323

Browse files
authored
Merge pull request #25161 from drodriguez/android-backtraces
[android] Basic support for backtraces.
2 parents b9917c3 + a702552 commit ad91323

File tree

2 files changed

+43
-1
lines changed

2 files changed

+43
-1
lines changed

cmake/modules/AddSwift.cmake

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,11 @@ function(_add_variant_c_compile_flags)
303303
"-fcoverage-mapping")
304304
endif()
305305

306+
if((CFLAGS_ARCH STREQUAL "armv7" OR CFLAGS_ARCH STREQUAL "aarch64") AND
307+
(CFLAGS_SDK STREQUAL "LINUX" OR CFLAGS_SDK STREQUAL "ANDROID"))
308+
list(APPEND result -funwind-tables)
309+
endif()
310+
306311
if("${CFLAGS_SDK}" STREQUAL "ANDROID")
307312
swift_android_libcxx_include_paths(CFLAGS_CXX_INCLUDES)
308313
swift_android_include_for_arch("${CFLAGS_ARCH}" "${CFLAGS_ARCH}_INCLUDE")

stdlib/public/runtime/Errors.cpp

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
//
1515
//===----------------------------------------------------------------------===//
1616

17-
#if defined(__CYGWIN__) || defined(__ANDROID__) || defined(__HAIKU__)
17+
#if defined(__CYGWIN__) || defined(__HAIKU__)
1818
#define SWIFT_SUPPORTS_BACKTRACE_REPORTING 0
1919
#else
2020
#define SWIFT_SUPPORTS_BACKTRACE_REPORTING 1
@@ -58,6 +58,10 @@
5858
#include <android/log.h>
5959
#endif
6060

61+
#if defined(__ELF__)
62+
#include <unwind.h>
63+
#endif
64+
6165
namespace FatalErrorFlags {
6266
enum: uint32_t {
6367
ReportBacktrace = 1 << 0
@@ -188,13 +192,46 @@ void swift::dumpStackTraceEntry(unsigned index, void *framePC,
188192
#endif
189193
}
190194

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+
191224
LLVM_ATTRIBUTE_NOINLINE
192225
void swift::printCurrentBacktrace(unsigned framesToSkip) {
193226
#if SWIFT_SUPPORTS_BACKTRACE_REPORTING
194227
constexpr unsigned maxSupportedStackDepth = 128;
195228
void *addrs[maxSupportedStackDepth];
196229
#if defined(_WIN32)
197230
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;
198235
#else
199236
int symbolCount = backtrace(addrs, maxSupportedStackDepth);
200237
#endif

0 commit comments

Comments
 (0)