aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSimon Hausmann <[email protected]>2013-10-01 16:34:21 +0200
committerThe Qt Project <[email protected]>2013-10-03 09:24:47 +0200
commit73dcd10dd060c6cc48f4def1c9cc39ca198acf6c (patch)
tree6f6918294bdd353f79af38aa64e2d31a471aa5b6 /src
parent7d9780b6308e15dcd4adcb65d7b516666c285f54 (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.cpp42
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;