blob: f6145dae70e844b4e5286c361c3a701654a39d56 [file] [log] [blame]
Ben Murdochf3b273f2017-01-17 12:11:28 +00001// 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 Xu7bc1b612021-02-16 09:38:50 +00005#ifndef V8_INSPECTOR_V8_DEBUGGER_AGENT_IMPL_H_
6#define V8_INSPECTOR_V8_DEBUGGER_AGENT_IMPL_H_
Ben Murdochf3b273f2017-01-17 12:11:28 +00007
Rubin Xu7bc1b612021-02-16 09:38:50 +00008#include <deque>
9#include <memory>
10#include <unordered_map>
Ben Murdochf3b273f2017-01-17 12:11:28 +000011#include <vector>
12
13#include "src/base/macros.h"
Rubin Xu7bc1b612021-02-16 09:38:50 +000014#include "src/debug/debug-interface.h"
Ben Murdoch62ed6312017-06-06 11:06:27 +010015#include "src/debug/interface-types.h"
Ben Murdochf3b273f2017-01-17 12:11:28 +000016#include "src/inspector/protocol/Debugger.h"
17#include "src/inspector/protocol/Forward.h"
18
19namespace v8_inspector {
20
21struct ScriptBreakpoint;
Ben Murdochf3b273f2017-01-17 12:11:28 +000022class V8Debugger;
23class V8DebuggerScript;
24class V8InspectorImpl;
25class V8InspectorSessionImpl;
26class V8Regex;
Ben Murdochf3b273f2017-01-17 12:11:28 +000027
Ben Murdochf3b273f2017-01-17 12:11:28 +000028using protocol::Maybe;
Ben Murdochc8c1d9e2017-03-08 14:04:23 +000029using protocol::Response;
Ben Murdochf3b273f2017-01-17 12:11:28 +000030
31class V8DebuggerAgentImpl : public protocol::Debugger::Backend {
32 public:
Ben Murdochf3b273f2017-01-17 12:11:28 +000033 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 Xu7bc1b612021-02-16 09:38:50 +000045 Response enable(Maybe<double> maxScriptsCacheSize,
46 String16* outDebuggerId) override;
Ben Murdochc8c1d9e2017-03-08 14:04:23 +000047 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 Xu7bc1b612021-02-16 09:38:50 +000052 Maybe<String16> optionalURLRegex, Maybe<String16> optionalScriptHash,
53 Maybe<int> optionalColumnNumber, Maybe<String16> optionalCondition,
54 String16*,
Ben Murdochf3b273f2017-01-17 12:11:28 +000055 std::unique_ptr<protocol::Array<protocol::Debugger::Location>>* locations)
56 override;
Ben Murdochc8c1d9e2017-03-08 14:04:23 +000057 Response setBreakpoint(
58 std::unique_ptr<protocol::Debugger::Location>,
59 Maybe<String16> optionalCondition, String16*,
Ben Murdochf3b273f2017-01-17 12:11:28 +000060 std::unique_ptr<protocol::Debugger::Location>* actualLocation) override;
Rubin Xu7bc1b612021-02-16 09:38:50 +000061 Response setBreakpointOnFunctionCall(const String16& functionObjectId,
62 Maybe<String16> optionalCondition,
63 String16* outBreakpointId) override;
64 Response setInstrumentationBreakpoint(const String16& instrumentation,
65 String16* outBreakpointId) override;
Ben Murdochc8c1d9e2017-03-08 14:04:23 +000066 Response removeBreakpoint(const String16& breakpointId) override;
Rubin Xu7bc1b612021-02-16 09:38:50 +000067 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 Murdochc8c1d9e2017-03-08 14:04:23 +000072 Response searchInContent(
73 const String16& scriptId, const String16& query,
74 Maybe<bool> optionalCaseSensitive, Maybe<bool> optionalIsRegex,
Ben Murdochf3b273f2017-01-17 12:11:28 +000075 std::unique_ptr<protocol::Array<protocol::Debugger::SearchMatch>>*)
76 override;
Ben Murdochc8c1d9e2017-03-08 14:04:23 +000077 Response getPossibleBreakpoints(
78 std::unique_ptr<protocol::Debugger::Location> start,
Rubin Xu7bc1b612021-02-16 09:38:50 +000079 Maybe<protocol::Debugger::Location> end, Maybe<bool> restrictToFunction,
80 std::unique_ptr<protocol::Array<protocol::Debugger::BreakLocation>>*
81 locations) override;
Ben Murdochc8c1d9e2017-03-08 14:04:23 +000082 Response setScriptSource(
83 const String16& inScriptId, const String16& inScriptSource,
84 Maybe<bool> dryRun,
Ben Murdochf3b273f2017-01-17 12:11:28 +000085 Maybe<protocol::Array<protocol::Debugger::CallFrame>>* optOutCallFrames,
86 Maybe<bool>* optOutStackChanged,
87 Maybe<protocol::Runtime::StackTrace>* optOutAsyncStackTrace,
Rubin Xu7bc1b612021-02-16 09:38:50 +000088 Maybe<protocol::Runtime::StackTraceId>* optOutAsyncStackTraceId,
Ben Murdochf3b273f2017-01-17 12:11:28 +000089 Maybe<protocol::Runtime::ExceptionDetails>* optOutCompileError) override;
Ben Murdochc8c1d9e2017-03-08 14:04:23 +000090 Response restartFrame(
91 const String16& callFrameId,
Ben Murdochf3b273f2017-01-17 12:11:28 +000092 std::unique_ptr<protocol::Array<protocol::Debugger::CallFrame>>*
93 newCallFrames,
Rubin Xu7bc1b612021-02-16 09:38:50 +000094 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 Murdochc8c1d9e2017-03-08 14:04:23 +0000100 Response pause() override;
Rubin Xu7bc1b612021-02-16 09:38:50 +0000101 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 Murdochc8c1d9e2017-03-08 14:04:23 +0000107 Response stepOut() override;
Rubin Xu7bc1b612021-02-16 09:38:50 +0000108 Response pauseOnAsyncCall(std::unique_ptr<protocol::Runtime::StackTraceId>
109 inParentStackTraceId) override;
Ben Murdochc8c1d9e2017-03-08 14:04:23 +0000110 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 Murdoch62ed6312017-06-06 11:06:27 +0100115 Maybe<bool> generatePreview, Maybe<bool> throwOnSideEffect,
Rubin Xu7bc1b612021-02-16 09:38:50 +0000116 Maybe<double> timeout,
Ben Murdochf3b273f2017-01-17 12:11:28 +0000117 std::unique_ptr<protocol::Runtime::RemoteObject>* result,
118 Maybe<protocol::Runtime::ExceptionDetails>*) override;
Rubin Xu7bc1b612021-02-16 09:38:50 +0000119 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 Murdochc8c1d9e2017-03-08 14:04:23 +0000124 Response setVariableValue(
125 int scopeNumber, const String16& variableName,
Ben Murdochf3b273f2017-01-17 12:11:28 +0000126 std::unique_ptr<protocol::Runtime::CallArgument> newValue,
127 const String16& callFrame) override;
Rubin Xu7bc1b612021-02-16 09:38:50 +0000128 Response setReturnValue(
129 std::unique_ptr<protocol::Runtime::CallArgument> newValue) override;
Ben Murdochc8c1d9e2017-03-08 14:04:23 +0000130 Response setAsyncCallStackDepth(int depth) override;
131 Response setBlackboxPatterns(
Ben Murdochf3b273f2017-01-17 12:11:28 +0000132 std::unique_ptr<protocol::Array<String16>> patterns) override;
Ben Murdochc8c1d9e2017-03-08 14:04:23 +0000133 Response setBlackboxedRanges(
134 const String16& scriptId,
Ben Murdochf3b273f2017-01-17 12:11:28 +0000135 std::unique_ptr<protocol::Array<protocol::Debugger::ScriptPosition>>
136 positions) override;
137
Rubin Xu7bc1b612021-02-16 09:38:50 +0000138 bool enabled() const { return m_enabled; }
Ben Murdochf3b273f2017-01-17 12:11:28 +0000139
Rubin Xu7bc1b612021-02-16 09:38:50 +0000140 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 Murdochf3b273f2017-01-17 12:11:28 +0000145 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 Murdochf3b273f2017-01-17 12:11:28 +0000151
152 void reset();
153
154 // Interface for V8InspectorImpl
Ben Murdoch62ed6312017-06-06 11:06:27 +0100155 void didPause(int contextId, v8::Local<v8::Value> exception,
Rubin Xu7bc1b612021-02-16 09:38:50 +0000156 const std::vector<v8::debug::BreakpointId>& hitBreakpoints,
157 v8::debug::ExceptionType exceptionType, bool isUncaught,
158 bool isOOMBreak, bool isAssert);
Ben Murdochf3b273f2017-01-17 12:11:28 +0000159 void didContinue();
160 void didParseSource(std::unique_ptr<V8DebuggerScript>, bool success);
Ben Murdochf3b273f2017-01-17 12:11:28 +0000161
Ben Murdoch62ed6312017-06-06 11:06:27 +0100162 bool isFunctionBlackboxed(const String16& scriptId,
163 const v8::debug::Location& start,
164 const v8::debug::Location& end);
Rubin Xu7bc1b612021-02-16 09:38:50 +0000165 bool shouldBeSkipped(const String16& scriptId, int line, int column);
Ben Murdoch62ed6312017-06-06 11:06:27 +0100166
Rubin Xu7bc1b612021-02-16 09:38:50 +0000167 bool acceptsPause(bool isOOMBreak) const;
168
169 void ScriptCollected(const V8DebuggerScript* script);
Ben Murdoch62ed6312017-06-06 11:06:27 +0100170
Ben Murdochf3b273f2017-01-17 12:11:28 +0000171 v8::Isolate* isolate() { return m_isolate; }
172
173 private:
Ben Murdochc8c1d9e2017-03-08 14:04:23 +0000174 void enableImpl();
Ben Murdochf3b273f2017-01-17 12:11:28 +0000175
Ben Murdochc8c1d9e2017-03-08 14:04:23 +0000176 Response currentCallFrames(
177 std::unique_ptr<protocol::Array<protocol::Debugger::CallFrame>>*);
Ben Murdochf3b273f2017-01-17 12:11:28 +0000178 std::unique_ptr<protocol::Runtime::StackTrace> currentAsyncStackTrace();
Rubin Xu7bc1b612021-02-16 09:38:50 +0000179 std::unique_ptr<protocol::Runtime::StackTraceId> currentExternalStackTrace();
Ben Murdochf3b273f2017-01-17 12:11:28 +0000180
Ben Murdochc8c1d9e2017-03-08 14:04:23 +0000181 void setPauseOnExceptionsImpl(int);
Ben Murdochf3b273f2017-01-17 12:11:28 +0000182
Rubin Xu7bc1b612021-02-16 09:38:50 +0000183 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 Murdochf3b273f2017-01-17 12:11:28 +0000191 void clearBreakDetails();
192
Ben Murdochf3b273f2017-01-17 12:11:28 +0000193 void internalSetAsyncCallStackDepth(int);
194 void increaseCachedSkipStackGeneration();
195
Ben Murdochc8c1d9e2017-03-08 14:04:23 +0000196 Response setBlackboxPattern(const String16& pattern);
Ben Murdoch62ed6312017-06-06 11:06:27 +0100197 void resetBlackboxedStateCache();
198
199 bool isPaused() const;
Ben Murdochf3b273f2017-01-17 12:11:28 +0000200
Rubin Xu7bc1b612021-02-16 09:38:50 +0000201 void setScriptInstrumentationBreakpointIfNeeded(V8DebuggerScript* script);
Ben Murdochf3b273f2017-01-17 12:11:28 +0000202
Rubin Xu7bc1b612021-02-16 09:38:50 +0000203 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 Murdochf3b273f2017-01-17 12:11:28 +0000212
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 Murdochf3b273f2017-01-17 12:11:28 +0000220 ScriptsMap m_scripts;
221 BreakpointIdToDebuggerBreakpointIdsMap m_breakpointIdToDebuggerBreakpointIds;
Rubin Xu7bc1b612021-02-16 09:38:50 +0000222 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 Murdochf3b273f2017-01-17 12:11:28 +0000230
Ben Murdoch62ed6312017-06-06 11:06:27 +0100231 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 Murdoch62ed6312017-06-06 11:06:27 +0100240 bool m_skipAllPauses = false;
Rubin Xu7bc1b612021-02-16 09:38:50 +0000241 bool m_breakpointsActive = false;
Ben Murdochf3b273f2017-01-17 12:11:28 +0000242
243 std::unique_ptr<V8Regex> m_blackboxPattern;
Rubin Xu7bc1b612021-02-16 09:38:50 +0000244 std::unordered_map<String16, std::vector<std::pair<int, int>>>
Ben Murdochf3b273f2017-01-17 12:11:28 +0000245 m_blackboxedPositions;
Rubin Xu7bc1b612021-02-16 09:38:50 +0000246 std::unordered_map<String16, std::vector<std::pair<int, int>>> m_skipList;
Ben Murdochf3b273f2017-01-17 12:11:28 +0000247
248 DISALLOW_COPY_AND_ASSIGN(V8DebuggerAgentImpl);
249};
250
251} // namespace v8_inspector
252
Rubin Xu7bc1b612021-02-16 09:38:50 +0000253#endif // V8_INSPECTOR_V8_DEBUGGER_AGENT_IMPL_H_