diff options
| author | Simon Hausmann <[email protected]> | 2013-10-01 16:34:21 +0200 |
|---|---|---|
| committer | The Qt Project <[email protected]> | 2013-10-03 09:24:47 +0200 |
| commit | 73dcd10dd060c6cc48f4def1c9cc39ca198acf6c (patch) | |
| tree | 6f6918294bdd353f79af38aa64e2d31a471aa5b6 /src | |
| parent | 7d9780b6308e15dcd4adcb65d7b516666c285f54 (diff) | |
Fix backtrace generation on Android/ARM/QNX
Use a GCC extension to the common C++ ABI's called _Unwind_Backtrace, which
generate backtraces if possible. Its direct use will ensure we use the
statically linked unwind, which knows about our unwind tables. This also helps
for the setup when libc doesn't have the glibc specific backtrace() function we
used previously. The unwinder on Mac OS X with clang also implements the same
extension.
Change-Id: I0b780590c10c16e50ec570f7da1efae2e64c46dd
Reviewed-by: Lars Knoll <[email protected]>
Diffstat (limited to 'src')
| -rw-r--r-- | src/qml/jsruntime/qv4stacktrace.cpp | 42 |
1 files changed, 37 insertions, 5 deletions
diff --git a/src/qml/jsruntime/qv4stacktrace.cpp b/src/qml/jsruntime/qv4stacktrace.cpp index 2a27c57e46..c715b629af 100644 --- a/src/qml/jsruntime/qv4stacktrace.cpp +++ b/src/qml/jsruntime/qv4stacktrace.cpp @@ -49,9 +49,41 @@ #include "qv4engine_p.h" #include "qv4unwindhelper_p.h" -#if (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID)) || defined(Q_OS_MAC) -#define HAVE_GNU_BACKTRACE -#include <execinfo.h> +#ifdef V4_CXX_ABI_EXCEPTION +#include <unwind.h> + +struct BacktraceHelper +{ + void **array; + int maximumSize; + int frameCount; +}; + +static _Unwind_Reason_Code bt_helper(struct _Unwind_Context *ctx, void *data) +{ + BacktraceHelper *helper = reinterpret_cast<BacktraceHelper*>(data); + + if (helper->frameCount != -1) { + helper->array[helper->frameCount] = (void*)_Unwind_GetIP(ctx); + + if (helper->frameCount > 0 && helper->array[helper->frameCount] == helper->array[helper->frameCount - 1]) + return _URC_END_OF_STACK; + } + ++helper->frameCount; + if (helper->frameCount == helper->maximumSize) + return _URC_END_OF_STACK; + return _URC_NO_REASON; +} + +static int get_backtrace_from_libunwind(void **array, int size) +{ + BacktraceHelper helper; + helper.array = array; + helper.maximumSize = size; + helper.frameCount = -1; // To skip this function + _Unwind_Backtrace(&bt_helper, &helper); + return helper.frameCount; +} #endif QT_BEGIN_NAMESPACE @@ -63,10 +95,10 @@ NativeStackTrace::NativeStackTrace(ExecutionContext *context) engine = context->engine; currentNativeFrame = 0; -#if defined(HAVE_GNU_BACKTRACE) +#ifdef V4_CXX_ABI_EXCEPTION UnwindHelper::prepareForUnwind(context); - nativeFrameCount = backtrace(&trace[0], sizeof(trace) / sizeof(trace[0])); + nativeFrameCount = get_backtrace_from_libunwind(&trace[0], sizeof(trace) / sizeof(trace[0])); #elif defined(Q_OS_WIN) && !defined(Q_OS_WINCE) int machineType = 0; |
