• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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