| 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 |