• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "InspectorFrontend.h"
34 #include "bindings/v8/ScriptState.h"
35 #include "core/inspector/AsyncCallStackTracker.h"
36 #include "core/inspector/ConsoleAPITypes.h"
37 #include "core/inspector/InjectedScript.h"
38 #include "core/inspector/InspectorBaseAgent.h"
39 #include "core/inspector/ScriptBreakpoint.h"
40 #include "core/inspector/ScriptDebugListener.h"
41 #include "core/frame/ConsoleTypes.h"
42 #include "wtf/Forward.h"
43 #include "wtf/HashMap.h"
44 #include "wtf/PassRefPtr.h"
45 #include "wtf/Vector.h"
46 #include "wtf/text/StringHash.h"
47 
48 namespace WebCore {
49 
50 class Document;
51 class InjectedScriptManager;
52 class InspectorFrontend;
53 class InstrumentingAgents;
54 class JSONObject;
55 class ScriptArguments;
56 class ScriptCallStack;
57 class ScriptDebugServer;
58 class ScriptSourceCode;
59 class ScriptValue;
60 class ScriptRegexp;
61 
62 typedef String ErrorString;
63 
64 class InspectorDebuggerAgent : public InspectorBaseAgent<InspectorDebuggerAgent>, public ScriptDebugListener, public InspectorBackendDispatcher::DebuggerCommandHandler {
65     WTF_MAKE_NONCOPYABLE(InspectorDebuggerAgent); WTF_MAKE_FAST_ALLOCATED;
66 public:
67     enum BreakpointSource {
68         UserBreakpointSource,
69         DebugCommandBreakpointSource,
70         MonitorCommandBreakpointSource
71     };
72 
73     static const char backtraceObjectGroup[];
74 
75     virtual ~InspectorDebuggerAgent();
76 
canSetScriptSource(ErrorString *,bool * result)77     virtual void canSetScriptSource(ErrorString*, bool* result) { *result = true; }
78 
79     virtual void setFrontend(InspectorFrontend*);
80     virtual void clearFrontend();
81     virtual void restore();
82 
83     bool isPaused();
84     bool runningNestedMessageLoop();
85     void addMessageToConsole(MessageSource, MessageType, MessageLevel, const String&, PassRefPtr<ScriptCallStack>, unsigned long);
86     void addMessageToConsole(MessageSource, MessageType, MessageLevel, const String&, ScriptState*, PassRefPtr<ScriptArguments>, unsigned long);
87 
88     String preprocessEventListener(Frame*, const String& source, const String& url, const String& functionName);
89     PassOwnPtr<ScriptSourceCode> preprocess(Frame*, const ScriptSourceCode&);
90 
91     // Part of the protocol.
92     virtual void enable(ErrorString*);
93     virtual void disable(ErrorString*);
94     virtual void setBreakpointsActive(ErrorString*, bool active);
95     virtual void setSkipAllPauses(ErrorString*, bool skipped, const bool* untilReload);
96 
97     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);
98     virtual void setBreakpoint(ErrorString*, const RefPtr<JSONObject>& location, const String* optionalCondition, TypeBuilder::Debugger::BreakpointId*, RefPtr<TypeBuilder::Debugger::Location>& actualLocation);
99     virtual void removeBreakpoint(ErrorString*, const String& breakpointId);
100     virtual void continueToLocation(ErrorString*, const RefPtr<JSONObject>& location, const bool* interstateLocationOpt);
101     virtual void getStepInPositions(ErrorString*, const String& callFrameId, RefPtr<TypeBuilder::Array<TypeBuilder::Debugger::Location> >& positions);
102     virtual void getBacktrace(ErrorString*, RefPtr<TypeBuilder::Array<TypeBuilder::Debugger::CallFrame> >&, RefPtr<TypeBuilder::Debugger::StackTrace>&);
103 
104     virtual void searchInContent(ErrorString*, const String& scriptId, const String& query, const bool* optionalCaseSensitive, const bool* optionalIsRegex, RefPtr<TypeBuilder::Array<TypeBuilder::Page::SearchMatch> >&);
105     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);
106     virtual void restartFrame(ErrorString*, const String& callFrameId, RefPtr<TypeBuilder::Array<TypeBuilder::Debugger::CallFrame> >& newCallFrames, RefPtr<JSONObject>& result, RefPtr<TypeBuilder::Debugger::StackTrace>& asyncStackTrace);
107     virtual void getScriptSource(ErrorString*, const String& scriptId, String* scriptSource);
108     virtual void getFunctionDetails(ErrorString*, const String& functionId, RefPtr<TypeBuilder::Debugger::FunctionDetails>&);
109     virtual void pause(ErrorString*);
110     virtual void resume(ErrorString*);
111     virtual void stepOver(ErrorString*, const String* callFrameId);
112     virtual void stepInto(ErrorString*);
113     virtual void stepOut(ErrorString*, const String* callFrameId);
114     virtual void setPauseOnExceptions(ErrorString*, const String& pauseState);
115     virtual void evaluateOnCallFrame(ErrorString*,
116                              const String& callFrameId,
117                              const String& expression,
118                              const String* objectGroup,
119                              const bool* includeCommandLineAPI,
120                              const bool* doNotPauseOnExceptionsAndMuteConsole,
121                              const bool* returnByValue,
122                              const bool* generatePreview,
123                              RefPtr<TypeBuilder::Runtime::RemoteObject>& result,
124                              TypeBuilder::OptOutput<bool>* wasThrown);
125     void compileScript(ErrorString*, const String& expression, const String& sourceURL, TypeBuilder::OptOutput<TypeBuilder::Debugger::ScriptId>*, TypeBuilder::OptOutput<String>* syntaxErrorMessage);
126     void runScript(ErrorString*, const TypeBuilder::Debugger::ScriptId&, const int* executionContextId, const String* objectGroup, const bool* doNotPauseOnExceptionsAndMuteConsole, RefPtr<TypeBuilder::Runtime::RemoteObject>& result, TypeBuilder::OptOutput<bool>* wasThrown);
127     virtual void setOverlayMessage(ErrorString*, const String*);
128     virtual void setVariableValue(ErrorString*, int in_scopeNumber, const String& in_variableName, const RefPtr<JSONObject>& in_newValue, const String* in_callFrame, const String* in_functionObjectId);
129     virtual void skipStackFrames(ErrorString*, const String* pattern);
130     virtual void setAsyncCallStackDepth(ErrorString*, int depth);
131 
132     void schedulePauseOnNextStatement(InspectorFrontend::Debugger::Reason::Enum breakReason, PassRefPtr<JSONObject> data);
133     void didInstallTimer(ExecutionContext*, int timerId, int timeout, bool singleShot);
134     void didRemoveTimer(ExecutionContext*, int timerId);
135     bool willFireTimer(ExecutionContext*, int timerId);
136     void didFireTimer();
137     void didRequestAnimationFrame(Document*, int callbackId);
138     void didCancelAnimationFrame(Document*, int callbackId);
139     bool willFireAnimationFrame(Document*, int callbackId);
140     void didFireAnimationFrame();
141     void didHandleEvent();
142     bool canBreakProgram();
143     void breakProgram(InspectorFrontend::Debugger::Reason::Enum breakReason, PassRefPtr<JSONObject> data);
144     virtual void scriptExecutionBlockedByCSP(const String& directiveText);
145 
146     class Listener {
147     public:
~Listener()148         virtual ~Listener() { }
149         virtual void debuggerWasEnabled() = 0;
150         virtual void debuggerWasDisabled() = 0;
151         virtual void stepInto() = 0;
152         virtual void didPause() = 0;
153     };
setListener(Listener * listener)154     void setListener(Listener* listener) { m_listener = listener; }
155 
156     virtual ScriptDebugServer& scriptDebugServer() = 0;
157 
158     void setBreakpoint(const String& scriptId, int lineNumber, int columnNumber, BreakpointSource, const String& condition = String());
159     void removeBreakpoint(const String& scriptId, int lineNumber, int columnNumber, BreakpointSource);
160 
161     SkipPauseRequest shouldSkipExceptionPause(RefPtr<JavaScriptCallFrame>& topFrame);
162     SkipPauseRequest shouldSkipBreakpointPause(RefPtr<JavaScriptCallFrame>& topFrame);
163     SkipPauseRequest shouldSkipStepPause(RefPtr<JavaScriptCallFrame>& topFrame);
164 
165 protected:
166     InspectorDebuggerAgent(InstrumentingAgents*, InspectorCompositeState*, InjectedScriptManager*);
167 
168     virtual void startListeningScriptDebugServer() = 0;
169     virtual void stopListeningScriptDebugServer() = 0;
170     virtual void muteConsole() = 0;
171     virtual void unmuteConsole() = 0;
injectedScriptManager()172     InjectedScriptManager* injectedScriptManager() { return m_injectedScriptManager; }
173     virtual InjectedScript injectedScriptForEval(ErrorString*, const int* executionContextId) = 0;
174 
175     virtual void enable();
176     virtual void disable();
177     virtual void didPause(ScriptState*, const ScriptValue& callFrames, const ScriptValue& exception, const Vector<String>& hitBreakpoints);
178     virtual void didContinue();
179     void reset();
180     void pageDidCommitLoad();
181 
182 private:
183     void cancelPauseOnNextStatement();
184     void addMessageToConsole(MessageSource, MessageType);
185 
186     bool enabled();
187 
188     PassRefPtr<TypeBuilder::Array<TypeBuilder::Debugger::CallFrame> > currentCallFrames();
189     PassRefPtr<TypeBuilder::Debugger::StackTrace> currentAsyncStackTrace();
190 
191     virtual void didParseSource(const String& scriptId, const Script&);
192     virtual void failedToParseSource(const String& url, const String& data, int firstLine, int errorLine, const String& errorMessage);
193 
194     void setPauseOnExceptionsImpl(ErrorString*, int);
195 
196     PassRefPtr<TypeBuilder::Debugger::Location> resolveBreakpoint(const String& breakpointId, const String& scriptId, const ScriptBreakpoint&, BreakpointSource);
197     void removeBreakpoint(const String& breakpointId);
198     void clear();
199     bool assertPaused(ErrorString*);
200     void clearBreakDetails();
201 
202     String sourceMapURLForScript(const Script&);
203 
204     String scriptURL(JavaScriptCallFrame*);
205 
206     ScriptValue resolveCallFrame(ErrorString*, const String* callFrameId);
207 
208     typedef HashMap<String, Script> ScriptsMap;
209     typedef HashMap<String, Vector<String> > BreakpointIdToDebugServerBreakpointIdsMap;
210     typedef HashMap<String, std::pair<String, BreakpointSource> > DebugServerBreakpointToBreakpointIdAndSourceMap;
211 
212     InjectedScriptManager* m_injectedScriptManager;
213     InspectorFrontend::Debugger* m_frontend;
214     ScriptState* m_pausedScriptState;
215     ScriptValue m_currentCallStack;
216     ScriptsMap m_scripts;
217     BreakpointIdToDebugServerBreakpointIdsMap m_breakpointIdToDebugServerBreakpointIds;
218     DebugServerBreakpointToBreakpointIdAndSourceMap m_serverBreakpoints;
219     String m_continueToLocationBreakpointId;
220     InspectorFrontend::Debugger::Reason::Enum m_breakReason;
221     RefPtr<JSONObject> m_breakAuxData;
222     bool m_javaScriptPauseScheduled;
223     Listener* m_listener;
224 
225     int m_skipStepInCount;
226     bool m_skipAllPauses;
227     OwnPtr<ScriptRegexp> m_cachedSkipStackRegExp;
228     AsyncCallStackTracker m_asyncCallStackTracker;
229 };
230 
231 } // namespace WebCore
232 
233 
234 #endif // !defined(InspectorDebuggerAgent_h)
235