Add a function dumping out a GBMI stack trace of the V4 engine.
authorFriedemann Kleint <Friedemann.Kleint@digia.com>
Fri, 20 Dec 2013 14:38:37 +0000 (15:38 +0100)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Wed, 12 Feb 2014 10:23:40 +0000 (11:23 +0100)
Add an exported C-function dumping the JS stack trace which can be
invoked by a debugger with the address of an execution context
it finds in a complete stack trace.

Task-number: QTCREATORBUG-11144
Change-Id: I5314f6b24868f12d4f9dedd1c261658957e581ba
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
src/qml/jsruntime/qv4engine.cpp

index 16bacbfafdc10526cc2367e5af981d47fda999dd..5a25a9f3b6575dd980c726765c83632a4750a90a 100644 (file)
@@ -68,6 +68,8 @@
 #include "qv4qobjectwrapper_p.h"
 #include "qv4qmlextensions_p.h"
 
+#include <QtCore/QTextStream>
+
 #ifdef V4_ENABLE_JIT
 #include "qv4isel_masm_p.h"
 #endif // V4_ENABLE_JIT
@@ -731,6 +733,39 @@ StackFrame ExecutionEngine::currentStackFrame() const
     return frame;
 }
 
+/* Helper and "C" linkage exported function to format a GDBMI stacktrace for
+ * invocation by a debugger.
+ * Sample GDB invocation: print qt_v4StackTrace((void*)0x7fffffffb290)
+ * Sample CDB invocation: .call Qt5Qmld!qt_v4StackTrace(0x7fffffffb290) ; gh
+ * Note: The helper is there to suppress MSVC warning 4190 about anything
+ * with UDT return types in a "C" linkage function. */
+
+static inline char *v4StackTrace(const ExecutionContext *context)
+{
+    QString result;
+    QTextStream str(&result);
+    str << "stack=[";
+    if (context && context->engine) {
+        const QVector<StackFrame> stackTrace = context->engine->stackTrace(20);
+        for (int i = 0; i < stackTrace.size(); ++i) {
+            if (i)
+                str << ',';
+            const QUrl url(stackTrace.at(i).source);
+            const QString fileName = url.isLocalFile() ? url.toLocalFile() : url.toString();
+            str << "frame={level=\"" << i << "\",func=\"" << stackTrace.at(i).function
+                << "\",file=\"" << fileName << "\",fullname=\"" << fileName
+                << "\",line=\"" << stackTrace.at(i).line << "\",language=\"js\"}";
+        }
+    }
+    str << ']';
+    return qstrdup(result.toLocal8Bit().constData());
+}
+
+extern "C" Q_QML_EXPORT char *qt_v4StackTrace(void *executionContext)
+{
+    return v4StackTrace(reinterpret_cast<const ExecutionContext *>(executionContext));
+}
+
 QUrl ExecutionEngine::resolvedUrl(const QString &file)
 {
     QUrl src(file);