Implement stack trace support for Windows
authorSimon Hausmann <simon.hausmann@digia.com>
Tue, 28 May 2013 07:36:04 +0000 (09:36 +0200)
committerLars Knoll <lars.knoll@digia.com>
Tue, 28 May 2013 13:26:39 +0000 (15:26 +0200)
Using StackWalk64

Change-Id: I8a4e1fe8f9338da60bd4b93b26f2cdfac2cf3cbb
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
src/qml/qml/v4/qv4engine.cpp
src/qml/qml/v4/v4.pri

index c7b32f4..cc3a5e2 100644 (file)
 #include <execinfo.h>
 #endif
 
+#if defined(Q_OS_WIN)
+#include <DbgHelp.h>
+#endif
+
 #ifdef V4_ENABLE_JIT
 #  include "qv4isel_masm_p.h"
 #else // !V4_ENABLE_JIT
@@ -583,6 +587,55 @@ namespace {
             UnwindHelper::prepareForUnwind(context);
 
             nativeFrameCount = backtrace(&trace[0], sizeof(trace) / sizeof(trace[0]));
+#elif defined(Q_OS_WIN)
+
+            int machineType = 0;
+
+            CONTEXT winContext;
+            memset(&winContext, 0, sizeof(winContext));
+            winContext.ContextFlags = CONTEXT_FULL;
+            RtlCaptureContext(&winContext);
+
+            STACKFRAME64 sf64;
+            memset(&sf64, 0, sizeof(sf64));
+
+#if defined(Q_PROCESSOR_X86)
+            machineType = IMAGE_FILE_MACHINE_I386;
+
+            sf64.AddrFrame.Offset = winContext.Ebp;
+            sf64.AddrFrame.Mode = AddrModeFlat;
+            sf64.AddrPC.Offset = winContext.Eip;
+            sf64.AddrPC.Mode = AddrModeFlat;
+            sf64.AddrStack.Offset = winContext.Esp;
+            sf64.AddrStack.Mode = AddrModeFlat;
+
+#elif defined(Q_PROCESSOR_X86_32)
+            machineType = IMAGE_FILE_MACHINE_AMD64;
+
+            sf64.AddrFrame.Offset = winContext.Rbp;
+            sf64.AddrFrame.Mode = AddrModeFlat;
+            sf64.AddrPC.Offset = winContext.Rip;
+            sf64.AddrPC.Mode = AddrModeFlat;
+            sf64.AddrStack.Offset = winContext.Rsp;
+            sf64.AddrStack.Mode = AddrModeFlat;
+
+#else
+#error "Platform unsupported!"
+#endif
+
+            nativeFrameCount = 0;
+
+            while (StackWalk64(machineType, GetCurrentProcess(), GetCurrentThread(), &sf64, &winContext, 0, SymFunctionTableAccess64, SymGetModuleBase64, 0)) {
+
+                if (sf64.AddrReturn.Offset == 0)
+                    break;
+
+                trace[nativeFrameCount] = reinterpret_cast<void*>(sf64.AddrReturn.Offset);
+                nativeFrameCount++;
+                if (nativeFrameCount >= sizeof(trace) / sizeof(trace[0]))
+                    break;
+            }
+
 #else
             nativeFrameCount = 0;
 #endif
index 0d1a55c..363133a 100644 (file)
@@ -185,6 +185,8 @@ valgrind {
 
 ios: DEFINES += ENABLE_ASSEMBLER_WX_EXCLUSIVE=1
 
+LIBS_PRIVATE += -lDbgHelp
+
 include(moth/moth.pri)
 include(../../../3rdparty/masm/masm.pri)
 include(../../../3rdparty/double-conversion/double-conversion.pri)