Home | History | Annotate | Download | only in inspector
      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 
     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:
    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     };
    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;
    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);
    254     AsyncCallStackTracker& asyncCallStackTracker() const { return *m_asyncCallStackTracker; };
    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