1 // Copyright 2015 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_DEBUGGER_AGENT_IMPL_H_ 6 #define V8_INSPECTOR_V8_DEBUGGER_AGENT_IMPL_H_ 7 8 #include <deque> 9 #include <unordered_map> 10 #include <vector> 11 12 #include "src/base/macros.h" 13 #include "src/debug/debug-interface.h" 14 #include "src/debug/interface-types.h" 15 #include "src/inspector/protocol/Debugger.h" 16 #include "src/inspector/protocol/Forward.h" 17 18 namespace v8_inspector { 19 20 struct ScriptBreakpoint; 21 class V8Debugger; 22 class V8DebuggerScript; 23 class V8InspectorImpl; 24 class V8InspectorSessionImpl; 25 class V8Regex; 26 27 using protocol::Maybe; 28 using protocol::Response; 29 30 class V8DebuggerAgentImpl : public protocol::Debugger::Backend { 31 public: 32 enum BreakpointSource { 33 UserBreakpointSource, 34 DebugCommandBreakpointSource, 35 MonitorCommandBreakpointSource 36 }; 37 38 V8DebuggerAgentImpl(V8InspectorSessionImpl*, protocol::FrontendChannel*, 39 protocol::DictionaryValue* state); 40 ~V8DebuggerAgentImpl() override; 41 void restore(); 42 43 // Part of the protocol. 44 Response enable(String16* outDebuggerId) override; 45 Response disable() override; 46 Response setBreakpointsActive(bool active) override; 47 Response setSkipAllPauses(bool skip) override; 48 Response setBreakpointByUrl( 49 int lineNumber, Maybe<String16> optionalURL, 50 Maybe<String16> optionalURLRegex, Maybe<String16> optionalScriptHash, 51 Maybe<int> optionalColumnNumber, Maybe<String16> optionalCondition, 52 String16*, 53 std::unique_ptr<protocol::Array<protocol::Debugger::Location>>* locations) 54 override; 55 Response setBreakpoint( 56 std::unique_ptr<protocol::Debugger::Location>, 57 Maybe<String16> optionalCondition, String16*, 58 std::unique_ptr<protocol::Debugger::Location>* actualLocation) override; 59 Response setBreakpointOnFunctionCall(const String16& functionObjectId, 60 Maybe<String16> optionalCondition, 61 String16* outBreakpointId) override; 62 Response removeBreakpoint(const String16& breakpointId) override; 63 Response continueToLocation(std::unique_ptr<protocol::Debugger::Location>, 64 Maybe<String16> targetCallFrames) override; 65 Response getStackTrace( 66 std::unique_ptr<protocol::Runtime::StackTraceId> inStackTraceId, 67 std::unique_ptr<protocol::Runtime::StackTrace>* outStackTrace) override; 68 Response searchInContent( 69 const String16& scriptId, const String16& query, 70 Maybe<bool> optionalCaseSensitive, Maybe<bool> optionalIsRegex, 71 std::unique_ptr<protocol::Array<protocol::Debugger::SearchMatch>>*) 72 override; 73 Response getPossibleBreakpoints( 74 std::unique_ptr<protocol::Debugger::Location> start, 75 Maybe<protocol::Debugger::Location> end, Maybe<bool> restrictToFunction, 76 std::unique_ptr<protocol::Array<protocol::Debugger::BreakLocation>>* 77 locations) override; 78 Response setScriptSource( 79 const String16& inScriptId, const String16& inScriptSource, 80 Maybe<bool> dryRun, 81 Maybe<protocol::Array<protocol::Debugger::CallFrame>>* optOutCallFrames, 82 Maybe<bool>* optOutStackChanged, 83 Maybe<protocol::Runtime::StackTrace>* optOutAsyncStackTrace, 84 Maybe<protocol::Runtime::StackTraceId>* optOutAsyncStackTraceId, 85 Maybe<protocol::Runtime::ExceptionDetails>* optOutCompileError) override; 86 Response restartFrame( 87 const String16& callFrameId, 88 std::unique_ptr<protocol::Array<protocol::Debugger::CallFrame>>* 89 newCallFrames, 90 Maybe<protocol::Runtime::StackTrace>* asyncStackTrace, 91 Maybe<protocol::Runtime::StackTraceId>* asyncStackTraceId) override; 92 Response getScriptSource(const String16& scriptId, 93 String16* scriptSource) override; 94 Response pause() override; 95 Response resume() override; 96 Response stepOver() override; 97 Response stepInto(Maybe<bool> inBreakOnAsyncCall) override; 98 Response stepOut() override; 99 void scheduleStepIntoAsync( 100 std::unique_ptr<ScheduleStepIntoAsyncCallback> callback) override; 101 Response pauseOnAsyncCall(std::unique_ptr<protocol::Runtime::StackTraceId> 102 inParentStackTraceId) override; 103 Response setPauseOnExceptions(const String16& pauseState) override; 104 Response evaluateOnCallFrame( 105 const String16& callFrameId, const String16& expression, 106 Maybe<String16> objectGroup, Maybe<bool> includeCommandLineAPI, 107 Maybe<bool> silent, Maybe<bool> returnByValue, 108 Maybe<bool> generatePreview, Maybe<bool> throwOnSideEffect, 109 Maybe<double> timeout, 110 std::unique_ptr<protocol::Runtime::RemoteObject>* result, 111 Maybe<protocol::Runtime::ExceptionDetails>*) override; 112 Response setVariableValue( 113 int scopeNumber, const String16& variableName, 114 std::unique_ptr<protocol::Runtime::CallArgument> newValue, 115 const String16& callFrame) override; 116 Response setReturnValue( 117 std::unique_ptr<protocol::Runtime::CallArgument> newValue) override; 118 Response setAsyncCallStackDepth(int depth) override; 119 Response setBlackboxPatterns( 120 std::unique_ptr<protocol::Array<String16>> patterns) override; 121 Response setBlackboxedRanges( 122 const String16& scriptId, 123 std::unique_ptr<protocol::Array<protocol::Debugger::ScriptPosition>> 124 positions) override; 125 enabled()126 bool enabled() const { return m_enabled; } 127 128 void setBreakpointFor(v8::Local<v8::Function> function, 129 v8::Local<v8::String> condition, 130 BreakpointSource source); 131 void removeBreakpointFor(v8::Local<v8::Function> function, 132 BreakpointSource source); 133 void schedulePauseOnNextStatement( 134 const String16& breakReason, 135 std::unique_ptr<protocol::DictionaryValue> data); 136 void cancelPauseOnNextStatement(); 137 void breakProgram(const String16& breakReason, 138 std::unique_ptr<protocol::DictionaryValue> data); 139 140 void reset(); 141 142 // Interface for V8InspectorImpl 143 void didPause(int contextId, v8::Local<v8::Value> exception, 144 const std::vector<v8::debug::BreakpointId>& hitBreakpoints, 145 bool isPromiseRejection, bool isUncaught, bool isOOMBreak, 146 bool isAssert); 147 void didContinue(); 148 void didParseSource(std::unique_ptr<V8DebuggerScript>, bool success); 149 150 bool isFunctionBlackboxed(const String16& scriptId, 151 const v8::debug::Location& start, 152 const v8::debug::Location& end); 153 154 bool acceptsPause(bool isOOMBreak) const; 155 isolate()156 v8::Isolate* isolate() { return m_isolate; } 157 158 private: 159 void enableImpl(); 160 161 Response currentCallFrames( 162 std::unique_ptr<protocol::Array<protocol::Debugger::CallFrame>>*); 163 std::unique_ptr<protocol::Runtime::StackTrace> currentAsyncStackTrace(); 164 std::unique_ptr<protocol::Runtime::StackTraceId> currentExternalStackTrace(); 165 std::unique_ptr<protocol::Runtime::StackTraceId> currentScheduledAsyncCall(); 166 167 void setPauseOnExceptionsImpl(int); 168 169 std::unique_ptr<protocol::Debugger::Location> setBreakpointImpl( 170 const String16& breakpointId, const String16& scriptId, 171 const String16& condition, int lineNumber, int columnNumber); 172 void setBreakpointImpl(const String16& breakpointId, 173 v8::Local<v8::Function> function, 174 v8::Local<v8::String> condition); 175 void removeBreakpointImpl(const String16& breakpointId); 176 void clearBreakDetails(); 177 178 void internalSetAsyncCallStackDepth(int); 179 void increaseCachedSkipStackGeneration(); 180 181 Response setBlackboxPattern(const String16& pattern); 182 void resetBlackboxedStateCache(); 183 184 bool isPaused() const; 185 186 using ScriptsMap = 187 std::unordered_map<String16, std::unique_ptr<V8DebuggerScript>>; 188 using BreakpointIdToDebuggerBreakpointIdsMap = 189 std::unordered_map<String16, std::vector<v8::debug::BreakpointId>>; 190 using DebuggerBreakpointIdToBreakpointIdMap = 191 std::unordered_map<v8::debug::BreakpointId, String16>; 192 193 V8InspectorImpl* m_inspector; 194 V8Debugger* m_debugger; 195 V8InspectorSessionImpl* m_session; 196 bool m_enabled; 197 protocol::DictionaryValue* m_state; 198 protocol::Debugger::Frontend m_frontend; 199 v8::Isolate* m_isolate; 200 ScriptsMap m_scripts; 201 BreakpointIdToDebuggerBreakpointIdsMap m_breakpointIdToDebuggerBreakpointIds; 202 DebuggerBreakpointIdToBreakpointIdMap m_debuggerBreakpointIdToBreakpointId; 203 204 std::deque<String16> m_failedToParseAnonymousScriptIds; 205 void cleanupOldFailedToParseAnonymousScriptsIfNeeded(); 206 207 using BreakReason = 208 std::pair<String16, std::unique_ptr<protocol::DictionaryValue>>; 209 std::vector<BreakReason> m_breakReason; 210 211 void pushBreakDetails( 212 const String16& breakReason, 213 std::unique_ptr<protocol::DictionaryValue> breakAuxData); 214 void popBreakDetails(); 215 216 bool m_skipAllPauses = false; 217 bool m_breakpointsActive = false; 218 219 std::unique_ptr<V8Regex> m_blackboxPattern; 220 std::unordered_map<String16, std::vector<std::pair<int, int>>> 221 m_blackboxedPositions; 222 223 DISALLOW_COPY_AND_ASSIGN(V8DebuggerAgentImpl); 224 }; 225 226 String16 scopeType(v8::debug::ScopeIterator::ScopeType type); 227 228 } // namespace v8_inspector 229 230 #endif // V8_INSPECTOR_V8_DEBUGGER_AGENT_IMPL_H_ 231