#include "sanitizer_platform.h"
#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \
SANITIZER_SOLARIS
#include "sanitizer_common.h"
#include "sanitizer_stacktrace.h"
#if SANITIZER_ANDROID
#include <dlfcn.h>
#endif
#if SANITIZER_FREEBSD
#define _GNU_SOURCE …
#endif
#include <unwind.h>
namespace __sanitizer {
namespace {
backtrace_frame_t;
extern "C" {
acquire_my_map_info_list_func;
release_my_map_info_list_func;
unwind_backtrace_signal_arch_func;
acquire_my_map_info_list_func acquire_my_map_info_list;
release_my_map_info_list_func release_my_map_info_list;
unwind_backtrace_signal_arch_func unwind_backtrace_signal_arch;
}
#if defined(__arm__) && !SANITIZER_NETBSD
#define UNWIND_STOP …
#define UNWIND_CONTINUE …
#else
#define UNWIND_STOP …
#define UNWIND_CONTINUE …
#endif
uptr Unwind_GetIP(struct _Unwind_Context *ctx) { … }
struct UnwindTraceArg { … };
_Unwind_Reason_Code Unwind_Trace(struct _Unwind_Context *ctx, void *param) { … }
}
#if SANITIZER_ANDROID
void SanitizerInitializeUnwinder() {
if (AndroidGetApiLevel() >= ANDROID_LOLLIPOP_MR1) return;
void *p = dlopen("libcorkscrew.so", RTLD_LAZY);
if (!p) {
VReport(1,
"Failed to open libcorkscrew.so. You may see broken stack traces "
"in SEGV reports.");
return;
}
acquire_my_map_info_list =
(acquire_my_map_info_list_func)(uptr)dlsym(p, "acquire_my_map_info_list");
release_my_map_info_list =
(release_my_map_info_list_func)(uptr)dlsym(p, "release_my_map_info_list");
unwind_backtrace_signal_arch = (unwind_backtrace_signal_arch_func)(uptr)dlsym(
p, "unwind_backtrace_signal_arch");
if (!acquire_my_map_info_list || !release_my_map_info_list ||
!unwind_backtrace_signal_arch) {
VReport(1,
"Failed to find one of the required symbols in libcorkscrew.so. "
"You may see broken stack traces in SEGV reports.");
acquire_my_map_info_list = 0;
unwind_backtrace_signal_arch = 0;
release_my_map_info_list = 0;
}
}
#endif
void BufferedStackTrace::UnwindSlow(uptr pc, u32 max_depth) { … }
void BufferedStackTrace::UnwindSlow(uptr pc, void *context, u32 max_depth) { … }
}
#endif