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