1 /* 2 * Copyright (C) 2010 Apple Inc. All rights reserved. 3 * Copyright (C) 2010-2011 Google Inc. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 15 * its contributors may be used to endorse or promote products derived 16 * from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #ifndef InspectorDebuggerAgent_h 31 #define InspectorDebuggerAgent_h 32 33 #include "bindings/core/v8/ScriptState.h" 34 #include "core/InspectorFrontend.h" 35 #include "core/frame/ConsoleTypes.h" 36 #include "core/inspector/AsyncCallStackTracker.h" 37 #include "core/inspector/ConsoleAPITypes.h" 38 #include "core/inspector/InjectedScript.h" 39 #include "core/inspector/InspectorBaseAgent.h" 40 #include "core/inspector/PromiseTracker.h" 41 #include "core/inspector/ScriptBreakpoint.h" 42 #include "core/inspector/ScriptDebugListener.h" 43 #include "wtf/Forward.h" 44 #include "wtf/HashMap.h" 45 #include "wtf/PassRefPtr.h" 46 #include "wtf/Vector.h" 47 #include "wtf/text/StringHash.h" 48 49 namespace blink { 50 51 class ConsoleMessage; 52 class Document; 53 class Event; 54 class EventListener; 55 class EventTarget; 56 class ExecutionContextTask; 57 class FormData; 58 class HTTPHeaderMap; 59 class InjectedScriptManager; 60 class InspectorFrontend; 61 class InstrumentingAgents; 62 class JavaScriptCallFrame; 63 class JSONObject; 64 class KURL; 65 class MutationObserver; 66 class ScriptArguments; 67 class ScriptAsyncCallStack; 68 class ScriptCallStack; 69 class ScriptDebugServer; 70 class ScriptRegexp; 71 class ScriptSourceCode; 72 class ScriptValue; 73 class ThreadableLoaderClient; 74 class XMLHttpRequest; 75 76 typedef String ErrorString; 77 78 class InspectorDebuggerAgent : public InspectorBaseAgent<InspectorDebuggerAgent>, public ScriptDebugListener, public InspectorBackendDispatcher::DebuggerCommandHandler { 79 WTF_MAKE_NONCOPYABLE(InspectorDebuggerAgent); 80 WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED; 81 public: 82 enum BreakpointSource { 83 UserBreakpointSource, 84 DebugCommandBreakpointSource, 85 MonitorCommandBreakpointSource 86 }; 87 88 static const char backtraceObjectGroup[]; 89 90 virtual ~InspectorDebuggerAgent(); 91 virtual void trace(Visitor*); 92 canSetScriptSource(ErrorString *,bool * result)93 virtual void canSetScriptSource(ErrorString*, bool* result) OVERRIDE FINAL { *result = true; } 94 95 virtual void init() OVERRIDE FINAL; 96 virtual void setFrontend(InspectorFrontend*) OVERRIDE FINAL; 97 virtual void clearFrontend() OVERRIDE FINAL; 98 virtual void restore() OVERRIDE FINAL; 99 100 bool isPaused(); 101 bool runningNestedMessageLoop(); 102 void addMessageToConsole(ConsoleMessage*); 103 104 String preprocessEventListener(LocalFrame*, const String& source, const String& url, const String& functionName); 105 PassOwnPtr<ScriptSourceCode> preprocess(LocalFrame*, const ScriptSourceCode&); 106 107 // Part of the protocol. 108 virtual void enable(ErrorString*) OVERRIDE FINAL; 109 virtual void disable(ErrorString*) OVERRIDE FINAL; 110 virtual void setBreakpointsActive(ErrorString*, bool active) OVERRIDE FINAL; 111 virtual void setSkipAllPauses(ErrorString*, bool skipped, const bool* untilReload) OVERRIDE FINAL; 112 113 virtual void setBreakpointByUrl(ErrorString*, int lineNumber, const String* optionalURL, const String* optionalURLRegex, const int* optionalColumnNumber, const String* optionalCondition, const bool* isAntiBreakpoint, TypeBuilder::Debugger::BreakpointId*, RefPtr<TypeBuilder::Array<TypeBuilder::Debugger::Location> >& locations) OVERRIDE FINAL; 114 virtual void setBreakpoint(ErrorString*, const RefPtr<JSONObject>& location, const String* optionalCondition, TypeBuilder::Debugger::BreakpointId*, RefPtr<TypeBuilder::Debugger::Location>& actualLocation) OVERRIDE FINAL; 115 virtual void removeBreakpoint(ErrorString*, const String& breakpointId) OVERRIDE FINAL; 116 virtual void continueToLocation(ErrorString*, const RefPtr<JSONObject>& location, const bool* interstateLocationOpt) OVERRIDE FINAL; 117 virtual void getStepInPositions(ErrorString*, const String& callFrameId, RefPtr<TypeBuilder::Array<TypeBuilder::Debugger::Location> >& positions) OVERRIDE FINAL; 118 virtual void getBacktrace(ErrorString*, RefPtr<TypeBuilder::Array<TypeBuilder::Debugger::CallFrame> >&, RefPtr<TypeBuilder::Debugger::StackTrace>&) OVERRIDE FINAL; 119 120 virtual void searchInContent(ErrorString*, const String& scriptId, const String& query, const bool* optionalCaseSensitive, const bool* optionalIsRegex, RefPtr<TypeBuilder::Array<TypeBuilder::Page::SearchMatch> >&) OVERRIDE FINAL; 121 virtual void setScriptSource(ErrorString*, RefPtr<TypeBuilder::Debugger::SetScriptSourceError>&, const String& scriptId, const String& newContent, const bool* preview, RefPtr<TypeBuilder::Array<TypeBuilder::Debugger::CallFrame> >& newCallFrames, RefPtr<JSONObject>& result, RefPtr<TypeBuilder::Debugger::StackTrace>& asyncStackTrace) OVERRIDE FINAL; 122 virtual void restartFrame(ErrorString*, const String& callFrameId, RefPtr<TypeBuilder::Array<TypeBuilder::Debugger::CallFrame> >& newCallFrames, RefPtr<JSONObject>& result, RefPtr<TypeBuilder::Debugger::StackTrace>& asyncStackTrace) OVERRIDE FINAL; 123 virtual void getScriptSource(ErrorString*, const String& scriptId, String* scriptSource) OVERRIDE FINAL; 124 virtual void getFunctionDetails(ErrorString*, const String& functionId, RefPtr<TypeBuilder::Debugger::FunctionDetails>&) OVERRIDE FINAL; 125 virtual void getCollectionEntries(ErrorString*, const String& objectId, RefPtr<TypeBuilder::Array<TypeBuilder::Debugger::CollectionEntry> >&) OVERRIDE FINAL; 126 virtual void pause(ErrorString*) OVERRIDE FINAL; 127 virtual void resume(ErrorString*) OVERRIDE FINAL; 128 virtual void stepOver(ErrorString*) OVERRIDE FINAL; 129 virtual void stepInto(ErrorString*) OVERRIDE FINAL; 130 virtual void stepOut(ErrorString*) OVERRIDE FINAL; 131 virtual void setPauseOnExceptions(ErrorString*, const String& pauseState) OVERRIDE FINAL; 132 virtual void evaluateOnCallFrame(ErrorString*, 133 const String& callFrameId, 134 const String& expression, 135 const String* objectGroup, 136 const bool* includeCommandLineAPI, 137 const bool* doNotPauseOnExceptionsAndMuteConsole, 138 const bool* returnByValue, 139 const bool* generatePreview, 140 RefPtr<TypeBuilder::Runtime::RemoteObject>& result, 141 TypeBuilder::OptOutput<bool>* wasThrown, 142 RefPtr<TypeBuilder::Debugger::ExceptionDetails>&) OVERRIDE FINAL; 143 virtual void compileScript(ErrorString*, const String& expression, const String& sourceURL, const int* executionContextId, TypeBuilder::OptOutput<TypeBuilder::Debugger::ScriptId>*, RefPtr<TypeBuilder::Debugger::ExceptionDetails>&) OVERRIDE; 144 virtual void runScript(ErrorString*, const TypeBuilder::Debugger::ScriptId&, const int* executionContextId, const String* objectGroup, const bool* doNotPauseOnExceptionsAndMuteConsole, RefPtr<TypeBuilder::Runtime::RemoteObject>& result, RefPtr<TypeBuilder::Debugger::ExceptionDetails>&) OVERRIDE; 145 virtual void setOverlayMessage(ErrorString*, const String*) OVERRIDE; 146 virtual void setVariableValue(ErrorString*, int in_scopeNumber, const String& in_variableName, const RefPtr<JSONObject>& in_newValue, const String* in_callFrame, const String* in_functionObjectId) OVERRIDE FINAL; 147 virtual void skipStackFrames(ErrorString*, const String* pattern, const bool* skipContentScripts) OVERRIDE FINAL; 148 virtual void setAsyncCallStackDepth(ErrorString*, int depth) OVERRIDE FINAL; 149 virtual void enablePromiseTracker(ErrorString*) OVERRIDE FINAL; 150 virtual void disablePromiseTracker(ErrorString*) OVERRIDE FINAL; 151 virtual void getPromises(ErrorString*, RefPtr<TypeBuilder::Array<TypeBuilder::Debugger::PromiseDetails> >& promises) OVERRIDE FINAL; 152 virtual void getPromiseById(ErrorString*, int promiseId, const String* objectGroup, RefPtr<TypeBuilder::Runtime::RemoteObject>& promise) OVERRIDE FINAL; 153 154 void schedulePauseOnNextStatement(InspectorFrontend::Debugger::Reason::Enum breakReason, PassRefPtr<JSONObject> data); 155 void didInstallTimer(ExecutionContext*, int timerId, int timeout, bool singleShot); 156 void didRemoveTimer(ExecutionContext*, int timerId); 157 bool willFireTimer(ExecutionContext*, int timerId); 158 void didFireTimer(); 159 void didRequestAnimationFrame(Document*, int callbackId); 160 void didCancelAnimationFrame(Document*, int callbackId); 161 bool willFireAnimationFrame(Document*, int callbackId); 162 void didFireAnimationFrame(); 163 void didEnqueueEvent(EventTarget*, Event*); 164 void didRemoveEvent(EventTarget*, Event*); 165 void willHandleEvent(EventTarget*, Event*, EventListener*, bool useCapture); 166 void didHandleEvent(); 167 void willLoadXHR(XMLHttpRequest*, ThreadableLoaderClient*, const AtomicString& method, const KURL&, bool async, PassRefPtr<FormData> body, const HTTPHeaderMap& headers, bool includeCrendentials); 168 void didDispatchXHRLoadendEvent(XMLHttpRequest*); 169 void didEnqueueMutationRecord(ExecutionContext*, MutationObserver*); 170 void didClearAllMutationRecords(ExecutionContext*, MutationObserver*); 171 void willDeliverMutationRecords(ExecutionContext*, MutationObserver*); 172 void didDeliverMutationRecords(); 173 void didPostExecutionContextTask(ExecutionContext*, ExecutionContextTask*); 174 void didKillAllExecutionContextTasks(ExecutionContext*); 175 void willPerformExecutionContextTask(ExecutionContext*, ExecutionContextTask*); 176 void didPerformExecutionContextTask(); 177 int traceAsyncOperationStarting(ExecutionContext*, const String& operationName, int prevOperationId = 0); 178 void traceAsyncOperationCompleted(ExecutionContext*, int operationId); 179 void traceAsyncOperationCompletedCallbackStarting(ExecutionContext*, int operationId); 180 void traceAsyncCallbackStarting(ExecutionContext*, int operationId); 181 void traceAsyncCallbackCompleted(); 182 bool canBreakProgram(); 183 void breakProgram(InspectorFrontend::Debugger::Reason::Enum breakReason, PassRefPtr<JSONObject> data); 184 void scriptExecutionBlockedByCSP(const String& directiveText); 185 186 class Listener : public WillBeGarbageCollectedMixin { 187 public: ~Listener()188 virtual ~Listener() { } 189 virtual void debuggerWasEnabled() = 0; 190 virtual void debuggerWasDisabled() = 0; 191 virtual void stepInto() = 0; 192 virtual void didPause() = 0; 193 virtual bool canPauseOnPromiseEvent() = 0; 194 virtual void didCreatePromise() = 0; 195 virtual void didResolvePromise() = 0; 196 virtual void didRejectPromise() = 0; 197 }; setListener(Listener * listener)198 void setListener(Listener* listener) { m_listener = listener; } 199 200 bool enabled(); 201 202 virtual ScriptDebugServer& scriptDebugServer() = 0; 203 204 void setBreakpoint(const String& scriptId, int lineNumber, int columnNumber, BreakpointSource, const String& condition = String()); 205 void removeBreakpoint(const String& scriptId, int lineNumber, int columnNumber, BreakpointSource); 206 207 PassRefPtrWillBeRawPtr<ScriptAsyncCallStack> currentAsyncStackTraceForConsole(); 208 209 protected: 210 explicit InspectorDebuggerAgent(InjectedScriptManager*); 211 212 virtual void startListeningScriptDebugServer() = 0; 213 virtual void stopListeningScriptDebugServer() = 0; 214 virtual void muteConsole() = 0; 215 virtual void unmuteConsole() = 0; injectedScriptManager()216 InjectedScriptManager* injectedScriptManager() { return m_injectedScriptManager; } 217 virtual InjectedScript injectedScriptForEval(ErrorString*, const int* executionContextId) = 0; 218 219 virtual void enable(); 220 virtual void disable(); 221 virtual SkipPauseRequest didPause(ScriptState*, const ScriptValue& callFrames, const ScriptValue& exception, const Vector<String>& hitBreakpoints) OVERRIDE FINAL; 222 virtual void didContinue() OVERRIDE FINAL; 223 void reset(); 224 void pageDidCommitLoad(); 225 226 private: 227 SkipPauseRequest shouldSkipExceptionPause(); 228 SkipPauseRequest shouldSkipStepPause(); 229 bool isTopCallFrameInFramework(); 230 231 void cancelPauseOnNextStatement(); 232 void addMessageToConsole(MessageSource, MessageType); 233 234 PassRefPtr<TypeBuilder::Array<TypeBuilder::Debugger::CallFrame> > currentCallFrames(); 235 PassRefPtr<TypeBuilder::Debugger::StackTrace> currentAsyncStackTrace(); 236 237 virtual void didParseSource(const String& scriptId, const Script&, CompileResult) OVERRIDE FINAL; 238 virtual bool v8AsyncTaskEventsEnabled() const OVERRIDE FINAL; 239 virtual void didReceiveV8AsyncTaskEvent(ExecutionContext*, const String& eventType, const String& eventName, int id) OVERRIDE FINAL; 240 virtual bool v8PromiseEventsEnabled() const OVERRIDE FINAL; 241 virtual void didReceiveV8PromiseEvent(ScriptState*, v8::Handle<v8::Object> promise, v8::Handle<v8::Value> parentPromise, int status) OVERRIDE FINAL; 242 243 void setPauseOnExceptionsImpl(ErrorString*, int); 244 245 PassRefPtr<TypeBuilder::Debugger::Location> resolveBreakpoint(const String& breakpointId, const String& scriptId, const ScriptBreakpoint&, BreakpointSource); 246 void removeBreakpoint(const String& breakpointId); 247 void clear(); 248 bool assertPaused(ErrorString*); 249 void clearBreakDetails(); 250 251 String sourceMapURLForScript(const Script&, CompileResult); 252 253 PassRefPtrWillBeRawPtr<JavaScriptCallFrame> topCallFrameSkipUnknownSources(String* scriptURL, bool* isBlackboxed); asyncCallStackTracker()254 AsyncCallStackTracker& asyncCallStackTracker() const { return *m_asyncCallStackTracker; }; promiseTracker()255 PromiseTracker& promiseTracker() const { return *m_promiseTracker; } 256 257 typedef HashMap<String, Script> ScriptsMap; 258 typedef HashMap<String, Vector<String> > BreakpointIdToDebugServerBreakpointIdsMap; 259 typedef HashMap<String, std::pair<String, BreakpointSource> > DebugServerBreakpointToBreakpointIdAndSourceMap; 260 261 RawPtrWillBeMember<InjectedScriptManager> m_injectedScriptManager; 262 InspectorFrontend::Debugger* m_frontend; 263 RefPtr<ScriptState> m_pausedScriptState; 264 ScriptValue m_currentCallStack; 265 ScriptsMap m_scripts; 266 BreakpointIdToDebugServerBreakpointIdsMap m_breakpointIdToDebugServerBreakpointIds; 267 DebugServerBreakpointToBreakpointIdAndSourceMap m_serverBreakpoints; 268 String m_continueToLocationBreakpointId; 269 InspectorFrontend::Debugger::Reason::Enum m_breakReason; 270 RefPtr<JSONObject> m_breakAuxData; 271 bool m_javaScriptPauseScheduled; 272 bool m_debuggerStepScheduled; 273 bool m_steppingFromFramework; 274 bool m_pausingOnNativeEvent; 275 RawPtrWillBeMember<Listener> m_listener; 276 277 int m_skippedStepInCount; 278 int m_minFrameCountForSkip; 279 bool m_skipAllPauses; 280 bool m_skipContentScripts; 281 OwnPtr<ScriptRegexp> m_cachedSkipStackRegExp; 282 OwnPtrWillBeMember<AsyncCallStackTracker> m_asyncCallStackTracker; 283 OwnPtrWillBeMember<PromiseTracker> m_promiseTracker; 284 }; 285 286 } // namespace blink 287 288 289 #endif // !defined(InspectorDebuggerAgent_h) 290