1 // Copyright 2016 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef V8_INSPECTOR_V8_STACK_TRACE_IMPL_H_ 6 #define V8_INSPECTOR_V8_STACK_TRACE_IMPL_H_ 7 8 #include <memory> 9 #include <vector> 10 11 #include "include/v8-inspector.h" 12 #include "include/v8.h" 13 #include "src/base/macros.h" 14 #include "src/inspector/protocol/Runtime.h" 15 #include "src/inspector/string-16.h" 16 17 namespace v8_inspector { 18 19 class AsyncStackTrace; 20 class V8Debugger; 21 class WasmTranslation; 22 struct V8StackTraceId; 23 24 class StackFrame { 25 public: 26 explicit StackFrame(v8::Isolate* isolate, v8::Local<v8::StackFrame> frame); 27 ~StackFrame() = default; 28 29 void translate(WasmTranslation* wasmTranslation); 30 31 const String16& functionName() const; 32 const String16& scriptId() const; 33 const String16& sourceURL() const; 34 int lineNumber() const; // 0-based. 35 int columnNumber() const; // 0-based. 36 std::unique_ptr<protocol::Runtime::CallFrame> buildInspectorObject( 37 V8InspectorClient* client) const; 38 bool isEqual(StackFrame* frame) const; 39 40 private: 41 String16 m_functionName; 42 String16 m_scriptId; 43 String16 m_sourceURL; 44 int m_lineNumber; // 0-based. 45 int m_columnNumber; // 0-based. 46 bool m_hasSourceURLComment; 47 }; 48 49 class V8StackTraceImpl : public V8StackTrace { 50 public: 51 static void setCaptureStackTraceForUncaughtExceptions(v8::Isolate*, 52 bool capture); 53 static int maxCallStackSizeToCapture; 54 static std::unique_ptr<V8StackTraceImpl> create(V8Debugger*, 55 int contextGroupId, 56 v8::Local<v8::StackTrace>, 57 int maxStackSize); 58 static std::unique_ptr<V8StackTraceImpl> capture(V8Debugger*, 59 int contextGroupId, 60 int maxStackSize); 61 62 ~V8StackTraceImpl() override; 63 std::unique_ptr<protocol::Runtime::StackTrace> buildInspectorObjectImpl( 64 V8Debugger* debugger) const; 65 66 // V8StackTrace implementation. 67 // This method drops the async stack trace. 68 std::unique_ptr<V8StackTrace> clone() override; 69 StringView firstNonEmptySourceURL() const override; 70 bool isEmpty() const override; 71 StringView topSourceURL() const override; 72 int topLineNumber() const override; // 1-based. 73 int topColumnNumber() const override; // 1-based. 74 StringView topScriptId() const override; 75 StringView topFunctionName() const override; 76 std::unique_ptr<protocol::Runtime::API::StackTrace> buildInspectorObject() 77 const override; 78 std::unique_ptr<StringBuffer> toString() const override; 79 80 bool isEqualIgnoringTopFrame(V8StackTraceImpl* stackTrace) const; 81 82 private: 83 V8StackTraceImpl(std::vector<std::shared_ptr<StackFrame>> frames, 84 int maxAsyncDepth, 85 std::shared_ptr<AsyncStackTrace> asyncParent, 86 const V8StackTraceId& externalParent); 87 88 class StackFrameIterator { 89 public: 90 explicit StackFrameIterator(const V8StackTraceImpl* stackTrace); 91 92 void next(); 93 StackFrame* frame(); 94 bool done(); 95 96 private: 97 std::vector<std::shared_ptr<StackFrame>>::const_iterator m_currentIt; 98 std::vector<std::shared_ptr<StackFrame>>::const_iterator m_currentEnd; 99 AsyncStackTrace* m_parent; 100 }; 101 102 std::vector<std::shared_ptr<StackFrame>> m_frames; 103 int m_maxAsyncDepth; 104 std::weak_ptr<AsyncStackTrace> m_asyncParent; 105 V8StackTraceId m_externalParent; 106 107 DISALLOW_COPY_AND_ASSIGN(V8StackTraceImpl); 108 }; 109 110 class AsyncStackTrace { 111 public: 112 static std::shared_ptr<AsyncStackTrace> capture(V8Debugger*, 113 int contextGroupId, 114 const String16& description, 115 int maxStackSize); 116 static uintptr_t store(V8Debugger* debugger, 117 std::shared_ptr<AsyncStackTrace> stack); 118 119 std::unique_ptr<protocol::Runtime::StackTrace> buildInspectorObject( 120 V8Debugger* debugger, int maxAsyncDepth) const; 121 122 // If async stack has suspended task id, it means that at moment when we 123 // capture current stack trace we suspended corresponded asynchronous 124 // execution flow and it is possible to request pause for a momemnt when 125 // that flow is resumed. 126 // E.g. every time when we suspend async function we mark corresponded async 127 // stack as suspended and every time when this function is resumed we remove 128 // suspendedTaskId. 129 void setSuspendedTaskId(void* task); 130 void* suspendedTaskId() const; 131 132 int contextGroupId() const; 133 const String16& description() const; 134 std::weak_ptr<AsyncStackTrace> parent() const; 135 bool isEmpty() const; externalParent()136 const V8StackTraceId& externalParent() const { return m_externalParent; } 137 frames()138 const std::vector<std::shared_ptr<StackFrame>>& frames() const { 139 return m_frames; 140 } 141 142 private: 143 AsyncStackTrace(int contextGroupId, const String16& description, 144 std::vector<std::shared_ptr<StackFrame>> frames, 145 std::shared_ptr<AsyncStackTrace> asyncParent, 146 const V8StackTraceId& externalParent); 147 148 int m_contextGroupId; 149 uintptr_t m_id; 150 void* m_suspendedTaskId; 151 String16 m_description; 152 153 std::vector<std::shared_ptr<StackFrame>> m_frames; 154 std::weak_ptr<AsyncStackTrace> m_asyncParent; 155 V8StackTraceId m_externalParent; 156 157 DISALLOW_COPY_AND_ASSIGN(AsyncStackTrace); 158 }; 159 160 } // namespace v8_inspector 161 162 #endif // V8_INSPECTOR_V8_STACK_TRACE_IMPL_H_ 163