Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion realm/realm-library/src/main/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ set(CMAKE_CXX_FLAGS_DEBUG "-ggdb -Og -DNDEBUG")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${REALM_COMMON_CXX_FLAGS} ${WARNING_CXX_FLAGS} ${ABI_CXX_FLAGS}")

# Set link flags
set(REALM_LINKER_FLAGS "")
set(REALM_LINKER_FLAGS "-Wl,--wrap=__cxa_throw")
if (build_SYNC)
set(REALM_LINKER_FLAGS "${REALM_LINKER_FLAGS} -lz")
endif()
Expand Down
65 changes: 65 additions & 0 deletions realm/realm-library/src/main/cpp/jni_util/exception_utils.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#include <unwind.h>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does API < 16 have libunwind?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you see anything about the API 16 with libunwind? I cannot find too much information about that.

But! https://code.google.com/p/android/issues/detail?id=199936

libunwind is not an NDK API. even if you get this to work now, in future releases you will be prevented from linking against libunwind at runtime.

:( :( :(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unwind.h exists in both R10e and R13b.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#include <dlfcn.h>
#include <iomanip>
#include <android/log.h>

struct BacktraceState
{
void** current;
void** end;
};

static _Unwind_Reason_Code unwindCallback(struct _Unwind_Context* context, void* arg)
{
BacktraceState* state = static_cast<BacktraceState*>(arg);
uintptr_t pc = _Unwind_GetIP(context);
if (pc) {
if (state->current == state->end) {
return _URC_END_OF_STACK;
} else {
*state->current++ = reinterpret_cast<void*>(pc);
}
}
return _URC_NO_REASON;
}

size_t captureBacktrace(void** buffer, size_t max)
{
BacktraceState state = {buffer, buffer + max};
_Unwind_Backtrace(unwindCallback, &state);

return state.current - buffer;
}

void dumpBacktrace(std::ostream& os, void** buffer, size_t count)
{
for (size_t idx = 0; idx < count; ++idx) {
uintptr_t addr = reinterpret_cast<uintptr_t>(buffer[idx]);
uintptr_t base_addr = 0;

Dl_info info;
if (dladdr(reinterpret_cast<void*>(addr), &info)) {
base_addr = reinterpret_cast<uintptr_t>(info.dli_fbase);
}

void* real_addr = (void *) (addr - base_addr);

os << " " << real_addr ;
}
}

extern "C" {
void __real___cxa_throw(void *ex, void *info, void (*dest)(void *));

void __wrap___cxa_throw(void *ex, void *info, void (*dest)(void *))
{
const size_t max = 30;
void* buffer[max];
std::ostringstream oss;

dumpBacktrace(oss, buffer, captureBacktrace(buffer, max));

__android_log_print(ANDROID_LOG_ERROR, "Backtrace for Native exception: ", "%s", oss.str().c_str());
__real___cxa_throw(ex,info,dest);
}
}