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 |