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_V8DEBUGGER_H_ 6 #define V8_INSPECTOR_V8DEBUGGER_H_ 7 8 #include <vector> 9 10 #include "src/base/macros.h" 11 #include "src/debug/debug-interface.h" 12 #include "src/inspector/java-script-call-frame.h" 13 #include "src/inspector/protocol/Forward.h" 14 #include "src/inspector/protocol/Runtime.h" 15 #include "src/inspector/v8-debugger-script.h" 16 #include "src/inspector/wasm-translation.h" 17 18 #include "include/v8-inspector.h" 19 20 namespace v8_inspector { 21 22 struct ScriptBreakpoint; 23 class V8DebuggerAgentImpl; 24 class V8InspectorImpl; 25 class V8StackTraceImpl; 26 27 using protocol::Response; 28 29 class V8Debugger : public v8::debug::DebugDelegate { 30 public: 31 V8Debugger(v8::Isolate*, V8InspectorImpl*); 32 ~V8Debugger(); 33 34 bool enabled() const; 35 36 String16 setBreakpoint(const ScriptBreakpoint&, int* actualLineNumber, 37 int* actualColumnNumber); 38 void removeBreakpoint(const String16& breakpointId); 39 void setBreakpointsActivated(bool); breakpointsActivated()40 bool breakpointsActivated() const { return m_breakpointsActivated; } 41 42 v8::debug::ExceptionBreakState getPauseOnExceptionsState(); 43 void setPauseOnExceptionsState(v8::debug::ExceptionBreakState); 44 void setPauseOnNextStatement(bool); 45 bool canBreakProgram(); 46 void breakProgram(); 47 void continueProgram(); 48 void stepIntoStatement(); 49 void stepOverStatement(); 50 void stepOutOfFunction(); 51 52 Response setScriptSource( 53 const String16& sourceID, v8::Local<v8::String> newSource, bool dryRun, 54 protocol::Maybe<protocol::Runtime::ExceptionDetails>*, 55 JavaScriptCallFrames* newCallFrames, protocol::Maybe<bool>* stackChanged, 56 bool* compileError); 57 JavaScriptCallFrames currentCallFrames(int limit = 0); 58 59 // Each script inherits debug data from v8::Context where it has been 60 // compiled. 61 // Only scripts whose debug data matches |contextGroupId| will be reported. 62 // Passing 0 will result in reporting all scripts. 63 void getCompiledScripts(int contextGroupId, 64 std::vector<std::unique_ptr<V8DebuggerScript>>&); 65 void enable(); 66 void disable(); 67 isPaused()68 bool isPaused() const { return m_runningNestedMessageLoop; } pausedContext()69 v8::Local<v8::Context> pausedContext() { return m_pausedContext; } 70 maxAsyncCallChainDepth()71 int maxAsyncCallChainDepth() { return m_maxAsyncCallStackDepth; } 72 V8StackTraceImpl* currentAsyncCallChain(); 73 void setAsyncCallStackDepth(V8DebuggerAgentImpl*, int); 74 std::unique_ptr<V8StackTraceImpl> createStackTrace(v8::Local<v8::StackTrace>); 75 std::unique_ptr<V8StackTraceImpl> captureStackTrace(bool fullStack); 76 77 v8::MaybeLocal<v8::Array> internalProperties(v8::Local<v8::Context>, 78 v8::Local<v8::Value>); 79 80 void asyncTaskScheduled(const StringView& taskName, void* task, 81 bool recurring); 82 void asyncTaskScheduled(const String16& taskName, void* task, bool recurring); 83 void asyncTaskCanceled(void* task); 84 void asyncTaskStarted(void* task); 85 void asyncTaskFinished(void* task); 86 void allAsyncTasksCanceled(); 87 88 void muteScriptParsedEvents(); 89 void unmuteScriptParsedEvents(); 90 inspector()91 V8InspectorImpl* inspector() { return m_inspector; } 92 wasmTranslation()93 WasmTranslation* wasmTranslation() { return &m_wasmTranslation; } 94 setMaxAsyncTaskStacksForTest(int limit)95 void setMaxAsyncTaskStacksForTest(int limit) { m_maxAsyncCallStacks = limit; } 96 97 private: 98 void compileDebuggerScript(); 99 v8::MaybeLocal<v8::Value> callDebuggerMethod(const char* functionName, 100 int argc, 101 v8::Local<v8::Value> argv[], 102 bool catchExceptions); 103 v8::Local<v8::Context> debuggerContext() const; 104 void clearBreakpoints(); 105 106 static void v8OOMCallback(void* data); 107 108 static void breakProgramCallback(const v8::FunctionCallbackInfo<v8::Value>&); 109 void handleProgramBreak(v8::Local<v8::Context> pausedContext, 110 v8::Local<v8::Object> executionState, 111 v8::Local<v8::Value> exception, 112 v8::Local<v8::Array> hitBreakpoints, 113 bool isPromiseRejection = false, 114 bool isUncaught = false); 115 116 enum ScopeTargetKind { 117 FUNCTION, 118 GENERATOR, 119 }; 120 v8::MaybeLocal<v8::Value> getTargetScopes(v8::Local<v8::Context>, 121 v8::Local<v8::Value>, 122 ScopeTargetKind); 123 124 v8::MaybeLocal<v8::Value> functionScopes(v8::Local<v8::Context>, 125 v8::Local<v8::Function>); 126 v8::MaybeLocal<v8::Value> generatorScopes(v8::Local<v8::Context>, 127 v8::Local<v8::Value>); 128 129 void asyncTaskCreated(void* task, void* parentTask); 130 void registerAsyncTaskIfNeeded(void* task); 131 132 // v8::debug::DebugEventListener implementation. 133 void PromiseEventOccurred(v8::debug::PromiseDebugActionType type, int id, 134 int parentId) override; 135 void ScriptCompiled(v8::Local<v8::debug::Script> script, 136 bool has_compile_error) override; 137 void BreakProgramRequested(v8::Local<v8::Context> paused_context, 138 v8::Local<v8::Object> exec_state, 139 v8::Local<v8::Value> break_points_hit) override; 140 void ExceptionThrown(v8::Local<v8::Context> paused_context, 141 v8::Local<v8::Object> exec_state, 142 v8::Local<v8::Value> exception, 143 v8::Local<v8::Value> promise, bool is_uncaught) override; 144 bool IsFunctionBlackboxed(v8::Local<v8::debug::Script> script, 145 const v8::debug::Location& start, 146 const v8::debug::Location& end) override; 147 148 v8::Isolate* m_isolate; 149 V8InspectorImpl* m_inspector; 150 int m_enableCount; 151 bool m_breakpointsActivated; 152 v8::Global<v8::Object> m_debuggerScript; 153 v8::Global<v8::Context> m_debuggerContext; 154 v8::Local<v8::Object> m_executionState; 155 v8::Local<v8::Context> m_pausedContext; 156 bool m_runningNestedMessageLoop; 157 int m_ignoreScriptParsedEventsCounter; 158 bool m_scheduledOOMBreak = false; 159 160 using AsyncTaskToStackTrace = 161 protocol::HashMap<void*, std::unique_ptr<V8StackTraceImpl>>; 162 AsyncTaskToStackTrace m_asyncTaskStacks; 163 AsyncTaskToStackTrace m_asyncTaskCreationStacks; 164 int m_maxAsyncCallStacks; 165 std::map<int, void*> m_idToTask; 166 std::unordered_map<void*, int> m_taskToId; 167 int m_lastTaskId; 168 protocol::HashSet<void*> m_recurringTasks; 169 int m_maxAsyncCallStackDepth; 170 std::vector<void*> m_currentTasks; 171 std::vector<std::unique_ptr<V8StackTraceImpl>> m_currentStacks; 172 protocol::HashMap<V8DebuggerAgentImpl*, int> m_maxAsyncCallStackDepthMap; 173 protocol::HashMap<void*, void*> m_parentTask; 174 175 v8::debug::ExceptionBreakState m_pauseOnExceptionsState; 176 177 WasmTranslation m_wasmTranslation; 178 179 DISALLOW_COPY_AND_ASSIGN(V8Debugger); 180 }; 181 182 } // namespace v8_inspector 183 184 #endif // V8_INSPECTOR_V8DEBUGGER_H_ 185