OLD | NEW |
| (Empty) |
1 // Copyright 2015 The Chromium 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 V8DebuggerAgent_h | |
6 #define V8DebuggerAgent_h | |
7 | |
8 #include "bindings/core/v8/ScriptState.h" | |
9 #include "bindings/core/v8/ScriptValue.h" | |
10 #include "core/CoreExport.h" | |
11 #include "core/InspectorFrontend.h" | |
12 #include "core/inspector/InspectorBaseAgent.h" | |
13 #include "core/inspector/PromiseTracker.h" | |
14 #include "core/inspector/v8/ScriptBreakpoint.h" | |
15 #include "core/inspector/v8/V8DebuggerListener.h" | |
16 #include "wtf/Forward.h" | |
17 #include "wtf/HashMap.h" | |
18 #include "wtf/HashSet.h" | |
19 #include "wtf/ListHashSet.h" | |
20 #include "wtf/PassRefPtr.h" | |
21 #include "wtf/Vector.h" | |
22 #include "wtf/text/StringHash.h" | |
23 | |
24 namespace blink { | |
25 | |
26 class AsyncCallChain; | |
27 class AsyncCallStack; | |
28 class DevToolsFunctionInfo; | |
29 class InjectedScript; | |
30 class InjectedScriptManager; | |
31 class JavaScriptCallFrame; | |
32 class JSONObject; | |
33 class RemoteCallFrameId; | |
34 class ScriptAsyncCallStack; | |
35 class ScriptRegexp; | |
36 class V8AsyncCallTracker; | |
37 class V8Debugger; | |
38 | |
39 typedef String ErrorString; | |
40 | |
41 class CORE_EXPORT V8DebuggerAgent | |
42 : public NoBaseWillBeGarbageCollectedFinalized<V8DebuggerAgent> | |
43 , public V8DebuggerListener | |
44 , public InspectorBackendDispatcher::DebuggerCommandHandler | |
45 , public PromiseTracker::Listener { | |
46 WTF_MAKE_NONCOPYABLE(V8DebuggerAgent); | |
47 WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED(V8DebuggerAgent); | |
48 WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(V8DebuggerAgent); | |
49 public: | |
50 enum BreakpointSource { | |
51 UserBreakpointSource, | |
52 DebugCommandBreakpointSource, | |
53 MonitorCommandBreakpointSource | |
54 }; | |
55 | |
56 static const char backtraceObjectGroup[]; | |
57 | |
58 class CORE_EXPORT Client { | |
59 public: | |
60 virtual ~Client() { } | |
61 virtual void debuggerAgentEnabled() = 0; | |
62 virtual void debuggerAgentDisabled() = 0; | |
63 virtual void muteConsole() = 0; | |
64 virtual void unmuteConsole() = 0; | |
65 virtual InjectedScript defaultInjectedScript() = 0; | |
66 }; | |
67 | |
68 V8DebuggerAgent(InjectedScriptManager*, V8Debugger*, Client*, int contextGro
upId); | |
69 ~V8DebuggerAgent() override; | |
70 DECLARE_TRACE(); | |
71 | |
72 void setInspectorState(InspectorState* state) { m_state = state; } | |
73 void setFrontend(InspectorFrontend::Debugger* frontend) { m_frontend = front
end; } | |
74 void clearFrontend(); | |
75 void restore(); | |
76 void disable(ErrorString*) final; | |
77 | |
78 bool isPaused(); | |
79 | |
80 // Part of the protocol. | |
81 void enable(ErrorString*) override; | |
82 void setBreakpointsActive(ErrorString*, bool active) final; | |
83 void setSkipAllPauses(ErrorString*, bool skipped) final; | |
84 | |
85 void setBreakpointByUrl(ErrorString*, int lineNumber, const String* optional
URL, const String* optionalURLRegex, const int* optionalColumnNumber, const Stri
ng* optionalCondition, TypeBuilder::Debugger::BreakpointId*, RefPtr<TypeBuilder:
:Array<TypeBuilder::Debugger::Location>>& locations) final; | |
86 void setBreakpoint(ErrorString*, const RefPtr<JSONObject>& location, const S
tring* optionalCondition, TypeBuilder::Debugger::BreakpointId*, RefPtr<TypeBuild
er::Debugger::Location>& actualLocation) final; | |
87 void removeBreakpoint(ErrorString*, const String& breakpointId) final; | |
88 void continueToLocation(ErrorString*, const RefPtr<JSONObject>& location, co
nst bool* interstateLocationOpt) final; | |
89 void getStepInPositions(ErrorString*, const String& callFrameId, RefPtr<Type
Builder::Array<TypeBuilder::Debugger::Location>>& positions) final; | |
90 void getBacktrace(ErrorString*, RefPtr<TypeBuilder::Array<TypeBuilder::Debug
ger::CallFrame>>&, RefPtr<TypeBuilder::Debugger::StackTrace>&) final; | |
91 void searchInContent(ErrorString*, const String& scriptId, const String& que
ry, const bool* optionalCaseSensitive, const bool* optionalIsRegex, RefPtr<TypeB
uilder::Array<TypeBuilder::Debugger::SearchMatch>>&) final; | |
92 void canSetScriptSource(ErrorString*, bool* result) final { *result = true;
} | |
93 void setScriptSource(ErrorString*, RefPtr<TypeBuilder::Debugger::SetScriptSo
urceError>&, const String& scriptId, const String& newContent, const bool* previ
ew, RefPtr<TypeBuilder::Array<TypeBuilder::Debugger::CallFrame>>& newCallFrames,
TypeBuilder::OptOutput<bool>* stackChanged, RefPtr<TypeBuilder::Debugger::Stack
Trace>& asyncStackTrace) final; | |
94 void restartFrame(ErrorString*, const String& callFrameId, RefPtr<TypeBuilde
r::Array<TypeBuilder::Debugger::CallFrame>>& newCallFrames, RefPtr<TypeBuilder::
Debugger::StackTrace>& asyncStackTrace) final; | |
95 void getScriptSource(ErrorString*, const String& scriptId, String* scriptSou
rce) final; | |
96 void getFunctionDetails(ErrorString*, const String& functionId, RefPtr<TypeB
uilder::Debugger::FunctionDetails>&) final; | |
97 void getGeneratorObjectDetails(ErrorString*, const String& objectId, RefPtr<
TypeBuilder::Debugger::GeneratorObjectDetails>&) final; | |
98 void getCollectionEntries(ErrorString*, const String& objectId, RefPtr<TypeB
uilder::Array<TypeBuilder::Debugger::CollectionEntry>>&) final; | |
99 void pause(ErrorString*) final; | |
100 void resume(ErrorString*) final; | |
101 void stepOver(ErrorString*) final; | |
102 void stepInto(ErrorString*) final; | |
103 void stepOut(ErrorString*) final; | |
104 void stepIntoAsync(ErrorString*) final; | |
105 void setPauseOnExceptions(ErrorString*, const String& pauseState) final; | |
106 void evaluateOnCallFrame(ErrorString*, | |
107 const String& callFrameId, | |
108 const String& expression, | |
109 const String* objectGroup, | |
110 const bool* includeCommandLineAPI, | |
111 const bool* doNotPauseOnExceptionsAndMuteConsole, | |
112 const bool* returnByValue, | |
113 const bool* generatePreview, | |
114 RefPtr<TypeBuilder::Runtime::RemoteObject>& result, | |
115 TypeBuilder::OptOutput<bool>* wasThrown, | |
116 RefPtr<TypeBuilder::Debugger::ExceptionDetails>&) final; | |
117 void compileScript(ErrorString*, const String& expression, const String& sou
rceURL, bool persistScript, const int* executionContextId, TypeBuilder::OptOutpu
t<TypeBuilder::Debugger::ScriptId>*, RefPtr<TypeBuilder::Debugger::ExceptionDeta
ils>&) override; | |
118 void runScript(ErrorString*, const TypeBuilder::Debugger::ScriptId&, const i
nt* executionContextId, const String* objectGroup, const bool* doNotPauseOnExcep
tionsAndMuteConsole, RefPtr<TypeBuilder::Runtime::RemoteObject>& result, RefPtr<
TypeBuilder::Debugger::ExceptionDetails>&) override; | |
119 void setVariableValue(ErrorString*, int in_scopeNumber, const String& in_var
iableName, const RefPtr<JSONObject>& in_newValue, const String* in_callFrame, co
nst String* in_functionObjectId) final; | |
120 void skipStackFrames(ErrorString*, const String* pattern, const bool* skipCo
ntentScripts) final; | |
121 void setAsyncCallStackDepth(ErrorString*, int depth) final; | |
122 void enablePromiseTracker(ErrorString*, const bool* captureStacks) final; | |
123 void disablePromiseTracker(ErrorString*) final; | |
124 void getPromiseById(ErrorString*, int promiseId, const String* objectGroup,
RefPtr<TypeBuilder::Runtime::RemoteObject>& promise) final; | |
125 void flushAsyncOperationEvents(ErrorString*) final; | |
126 void setAsyncOperationBreakpoint(ErrorString*, int operationId) final; | |
127 void removeAsyncOperationBreakpoint(ErrorString*, int operationId) final; | |
128 | |
129 void schedulePauseOnNextStatement(InspectorFrontend::Debugger::Reason::Enum
breakReason, PassRefPtr<JSONObject> data); | |
130 void cancelPauseOnNextStatement(); | |
131 bool canBreakProgram(); | |
132 void breakProgram(InspectorFrontend::Debugger::Reason::Enum breakReason, Pas
sRefPtr<JSONObject> data); | |
133 void willExecuteScript(int scriptId); | |
134 void didExecuteScript(); | |
135 | |
136 bool enabled(); | |
137 V8Debugger& debugger() { return *m_debugger; } | |
138 | |
139 void setBreakpoint(const String& scriptId, int lineNumber, int columnNumber,
BreakpointSource, const String& condition = String()); | |
140 void removeBreakpoint(const String& scriptId, int lineNumber, int columnNumb
er, BreakpointSource); | |
141 | |
142 // Async call stacks implementation | |
143 PassRefPtrWillBeRawPtr<ScriptAsyncCallStack> currentAsyncStackTraceForConsol
e(); | |
144 static const int unknownAsyncOperationId; | |
145 int traceAsyncOperationStarting(const String& description); | |
146 void traceAsyncCallbackStarting(int operationId); | |
147 void traceAsyncCallbackCompleted(); | |
148 void traceAsyncOperationCompleted(int operationId); | |
149 bool trackingAsyncCalls() const { return m_maxAsyncCallStackDepth; } | |
150 | |
151 class CORE_EXPORT AsyncCallTrackingListener : public WillBeGarbageCollectedM
ixin { | |
152 public: | |
153 virtual ~AsyncCallTrackingListener() { } | |
154 DEFINE_INLINE_VIRTUAL_TRACE() { } | |
155 virtual void asyncCallTrackingStateChanged(bool tracking) = 0; | |
156 virtual void resetAsyncOperations() = 0; | |
157 }; | |
158 void addAsyncCallTrackingListener(AsyncCallTrackingListener*); | |
159 void removeAsyncCallTrackingListener(AsyncCallTrackingListener*); | |
160 | |
161 // PromiseTracker::Listener | |
162 void didUpdatePromise(InspectorFrontend::Debugger::EventType::Enum, PassRefP
tr<TypeBuilder::Debugger::PromiseDetails>) final; | |
163 | |
164 InjectedScript injectedScriptForEval(ErrorString*, const int* executionConte
xtId); | |
165 InjectedScriptManager* injectedScriptManager() { return m_injectedScriptMana
ger; } | |
166 void reset(); | |
167 | |
168 private: | |
169 bool checkEnabled(ErrorString*); | |
170 void enable(); | |
171 | |
172 SkipPauseRequest didPause(v8::Local<v8::Context>, v8::Local<v8::Object> call
Frames, v8::Local<v8::Value> exception, const Vector<String>& hitBreakpoints, bo
ol isPromiseRejection) final; | |
173 void didContinue() final; | |
174 | |
175 SkipPauseRequest shouldSkipExceptionPause(); | |
176 SkipPauseRequest shouldSkipStepPause(); | |
177 | |
178 void schedulePauseOnNextStatementIfSteppingInto(); | |
179 | |
180 PassRefPtr<TypeBuilder::Array<TypeBuilder::Debugger::CallFrame>> currentCall
Frames(); | |
181 PassRefPtr<TypeBuilder::Debugger::StackTrace> currentAsyncStackTrace(); | |
182 bool callStackForId(ErrorString*, const RemoteCallFrameId&, v8::Local<v8::Ob
ject>* callStack, bool* isAsync); | |
183 | |
184 void clearCurrentAsyncOperation(); | |
185 void resetAsyncCallTracker(); | |
186 | |
187 void changeJavaScriptRecursionLevel(int step); | |
188 | |
189 void didParseSource(const ParsedScript&) final; | |
190 bool v8AsyncTaskEventsEnabled() const final; | |
191 void didReceiveV8AsyncTaskEvent(v8::Local<v8::Context>, const String& eventT
ype, const String& eventName, int id) final; | |
192 bool v8PromiseEventsEnabled() const final; | |
193 void didReceiveV8PromiseEvent(v8::Local<v8::Context>, v8::Local<v8::Object>
promise, v8::Local<v8::Value> parentPromise, int status) final; | |
194 | |
195 void setPauseOnExceptionsImpl(ErrorString*, int); | |
196 | |
197 PassRefPtr<TypeBuilder::Debugger::Location> resolveBreakpoint(const String&
breakpointId, const String& scriptId, const ScriptBreakpoint&, BreakpointSource)
; | |
198 void removeBreakpoint(const String& breakpointId); | |
199 void clearStepIntoAsync(); | |
200 bool assertPaused(ErrorString*); | |
201 void clearBreakDetails(); | |
202 | |
203 String sourceMapURLForScript(const Script&, CompileResult); | |
204 | |
205 bool isCallStackEmptyOrBlackboxed(); | |
206 bool isTopCallFrameBlackboxed(); | |
207 bool isCallFrameWithUnknownScriptOrBlackboxed(PassRefPtr<JavaScriptCallFrame
>); | |
208 | |
209 void internalSetAsyncCallStackDepth(int); | |
210 void increaseCachedSkipStackGeneration(); | |
211 PassRefPtr<TypeBuilder::Debugger::ExceptionDetails> createExceptionDetails(v
8::Isolate*, v8::Local<v8::Message>); | |
212 | |
213 typedef HashMap<String, Script> ScriptsMap; | |
214 typedef HashMap<String, Vector<String>> BreakpointIdToDebuggerBreakpointIdsM
ap; | |
215 typedef HashMap<String, std::pair<String, BreakpointSource>> DebugServerBrea
kpointToBreakpointIdAndSourceMap; | |
216 | |
217 enum DebuggerStep { | |
218 NoStep = 0, | |
219 StepInto, | |
220 StepOver, | |
221 StepOut | |
222 }; | |
223 | |
224 RawPtrWillBeMember<InjectedScriptManager> m_injectedScriptManager; | |
225 V8Debugger* m_debugger; | |
226 Client* m_client; | |
227 int m_contextGroupId; | |
228 InspectorState* m_state; | |
229 InspectorFrontend::Debugger* m_frontend; | |
230 v8::Isolate* m_isolate; | |
231 RefPtr<ScriptState> m_pausedScriptState; | |
232 v8::Global<v8::Object> m_currentCallStack; | |
233 ScriptsMap m_scripts; | |
234 BreakpointIdToDebuggerBreakpointIdsMap m_breakpointIdToDebuggerBreakpointIds
; | |
235 DebugServerBreakpointToBreakpointIdAndSourceMap m_serverBreakpoints; | |
236 String m_continueToLocationBreakpointId; | |
237 InspectorFrontend::Debugger::Reason::Enum m_breakReason; | |
238 RefPtr<JSONObject> m_breakAuxData; | |
239 DebuggerStep m_scheduledDebuggerStep; | |
240 bool m_skipNextDebuggerStepOut; | |
241 bool m_javaScriptPauseScheduled; | |
242 bool m_steppingFromFramework; | |
243 bool m_pausingOnNativeEvent; | |
244 bool m_pausingOnAsyncOperation; | |
245 | |
246 int m_skippedStepFrameCount; | |
247 int m_recursionLevelForStepOut; | |
248 int m_recursionLevelForStepFrame; | |
249 bool m_skipAllPauses; | |
250 bool m_skipContentScripts; | |
251 OwnPtr<ScriptRegexp> m_cachedSkipStackRegExp; | |
252 unsigned m_cachedSkipStackGeneration; | |
253 WillBeHeapHashSet<RawPtrWillBeWeakMember<AsyncCallTrackingListener>> m_async
CallTrackingListeners; | |
254 // This field must be destroyed before the listeners set above. | |
255 OwnPtrWillBeMember<V8AsyncCallTracker> m_v8AsyncCallTracker; | |
256 OwnPtrWillBeMember<PromiseTracker> m_promiseTracker; | |
257 | |
258 using AsyncOperationIdToAsyncCallChain = WillBeHeapHashMap<int, RefPtrWillBe
Member<AsyncCallChain>>; | |
259 AsyncOperationIdToAsyncCallChain m_asyncOperations; | |
260 int m_lastAsyncOperationId; | |
261 ListHashSet<int> m_asyncOperationNotifications; | |
262 HashSet<int> m_asyncOperationBreakpoints; | |
263 HashSet<int> m_pausingAsyncOperations; | |
264 unsigned m_maxAsyncCallStackDepth; | |
265 RefPtrWillBeMember<AsyncCallChain> m_currentAsyncCallChain; | |
266 unsigned m_nestedAsyncCallCount; | |
267 int m_currentAsyncOperationId; | |
268 bool m_pendingTraceAsyncOperationCompleted; | |
269 bool m_startingStepIntoAsync; | |
270 V8GlobalValueMap<String, v8::Script, v8::kNotWeak> m_compiledScripts; | |
271 }; | |
272 | |
273 } // namespace blink | |
274 | |
275 | |
276 #endif // V8DebuggerAgent_h | |
OLD | NEW |