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