Line data Source code
1 : // Copyright 2016 the V8 project 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 V8_INSPECTOR_V8DEBUGGER_H_
6 : #define V8_INSPECTOR_V8DEBUGGER_H_
7 :
8 : #include <list>
9 : #include <vector>
10 :
11 : #include "src/base/macros.h"
12 : #include "src/debug/debug-interface.h"
13 : #include "src/inspector/java-script-call-frame.h"
14 : #include "src/inspector/protocol/Debugger.h"
15 : #include "src/inspector/protocol/Forward.h"
16 : #include "src/inspector/protocol/Runtime.h"
17 : #include "src/inspector/v8-debugger-script.h"
18 : #include "src/inspector/wasm-translation.h"
19 :
20 : #include "include/v8-inspector.h"
21 :
22 : namespace v8_inspector {
23 :
24 : class AsyncStackTrace;
25 : struct ScriptBreakpoint;
26 : class StackFrame;
27 : class V8Debugger;
28 : class V8DebuggerAgentImpl;
29 : class V8InspectorImpl;
30 : class V8StackTraceImpl;
31 :
32 : using protocol::Response;
33 : using ScheduleStepIntoAsyncCallback =
34 : protocol::Debugger::Backend::ScheduleStepIntoAsyncCallback;
35 :
36 : class V8Debugger : public v8::debug::DebugDelegate {
37 : public:
38 : V8Debugger(v8::Isolate*, V8InspectorImpl*);
39 : ~V8Debugger();
40 :
41 : bool enabled() const;
42 : v8::Isolate* isolate() const { return m_isolate; }
43 :
44 : String16 setBreakpoint(const ScriptBreakpoint&, int* actualLineNumber,
45 : int* actualColumnNumber);
46 : void removeBreakpoint(const String16& breakpointId);
47 : void setBreakpointsActivated(bool);
48 : bool breakpointsActivated() const { return m_breakpointsActivated; }
49 :
50 : v8::debug::ExceptionBreakState getPauseOnExceptionsState();
51 : void setPauseOnExceptionsState(v8::debug::ExceptionBreakState);
52 : bool canBreakProgram();
53 : bool breakProgram(int targetContextGroupId);
54 : void continueProgram(int targetContextGroupId);
55 :
56 : void setPauseOnNextStatement(bool, int targetContextGroupId);
57 : void stepIntoStatement(int targetContextGroupId);
58 : void stepOverStatement(int targetContextGroupId);
59 : void stepOutOfFunction(int targetContextGroupId);
60 : void scheduleStepIntoAsync(
61 : std::unique_ptr<ScheduleStepIntoAsyncCallback> callback,
62 : int targetContextGroupId);
63 :
64 : Response setScriptSource(
65 : const String16& sourceID, v8::Local<v8::String> newSource, bool dryRun,
66 : protocol::Maybe<protocol::Runtime::ExceptionDetails>*,
67 : JavaScriptCallFrames* newCallFrames, protocol::Maybe<bool>* stackChanged,
68 : bool* compileError);
69 : JavaScriptCallFrames currentCallFrames(int limit = 0);
70 :
71 : // Each script inherits debug data from v8::Context where it has been
72 : // compiled.
73 : // Only scripts whose debug data matches |contextGroupId| will be reported.
74 : // Passing 0 will result in reporting all scripts.
75 : void getCompiledScripts(int contextGroupId,
76 : std::vector<std::unique_ptr<V8DebuggerScript>>&);
77 : void enable();
78 : void disable();
79 :
80 0 : bool isPaused() const { return m_pausedContextGroupId; }
81 : v8::Local<v8::Context> pausedContext() { return m_pausedContext; }
82 :
83 : int maxAsyncCallChainDepth() { return m_maxAsyncCallStackDepth; }
84 : void setAsyncCallStackDepth(V8DebuggerAgentImpl*, int);
85 :
86 : std::shared_ptr<AsyncStackTrace> currentAsyncParent();
87 : std::shared_ptr<AsyncStackTrace> currentAsyncCreation();
88 :
89 : std::shared_ptr<StackFrame> symbolize(v8::Local<v8::StackFrame> v8Frame);
90 :
91 : std::unique_ptr<V8StackTraceImpl> createStackTrace(v8::Local<v8::StackTrace>);
92 : std::unique_ptr<V8StackTraceImpl> captureStackTrace(bool fullStack);
93 :
94 : v8::MaybeLocal<v8::Array> internalProperties(v8::Local<v8::Context>,
95 : v8::Local<v8::Value>);
96 :
97 : void asyncTaskScheduled(const StringView& taskName, void* task,
98 : bool recurring);
99 : void asyncTaskCanceled(void* task);
100 : void asyncTaskStarted(void* task);
101 : void asyncTaskFinished(void* task);
102 : void allAsyncTasksCanceled();
103 :
104 : void muteScriptParsedEvents();
105 : void unmuteScriptParsedEvents();
106 :
107 : V8InspectorImpl* inspector() { return m_inspector; }
108 :
109 : WasmTranslation* wasmTranslation() { return &m_wasmTranslation; }
110 :
111 : void setMaxAsyncTaskStacksForTest(int limit);
112 : void dumpAsyncTaskStacksStateForTest();
113 :
114 : private:
115 : void compileDebuggerScript();
116 : v8::MaybeLocal<v8::Value> callDebuggerMethod(const char* functionName,
117 : int argc,
118 : v8::Local<v8::Value> argv[],
119 : bool catchExceptions);
120 : v8::Local<v8::Context> debuggerContext() const;
121 : void clearBreakpoints();
122 :
123 : static void v8OOMCallback(void* data);
124 :
125 : void handleProgramBreak(v8::Local<v8::Context> pausedContext,
126 : v8::Local<v8::Object> executionState,
127 : v8::Local<v8::Value> exception,
128 : v8::Local<v8::Array> hitBreakpoints,
129 : bool isPromiseRejection = false,
130 : bool isUncaught = false);
131 :
132 : enum ScopeTargetKind {
133 : FUNCTION,
134 : GENERATOR,
135 : };
136 : v8::MaybeLocal<v8::Value> getTargetScopes(v8::Local<v8::Context>,
137 : v8::Local<v8::Value>,
138 : ScopeTargetKind);
139 :
140 : v8::MaybeLocal<v8::Value> functionScopes(v8::Local<v8::Context>,
141 : v8::Local<v8::Function>);
142 : v8::MaybeLocal<v8::Value> generatorScopes(v8::Local<v8::Context>,
143 : v8::Local<v8::Value>);
144 :
145 : void asyncTaskCreatedForStack(void* task, void* parentTask);
146 : void asyncTaskScheduledForStack(const String16& taskName, void* task,
147 : bool recurring);
148 : void asyncTaskCanceledForStack(void* task);
149 : void asyncTaskStartedForStack(void* task);
150 : void asyncTaskFinishedForStack(void* task);
151 :
152 : void asyncTaskCandidateForStepping(void* task);
153 : void asyncTaskStartedForStepping(void* task);
154 : void asyncTaskFinishedForStepping(void* task);
155 : void asyncTaskCanceledForStepping(void* task);
156 :
157 : // v8::debug::DebugEventListener implementation.
158 : void PromiseEventOccurred(v8::debug::PromiseDebugActionType type, int id,
159 : int parentId, bool createdByUser) override;
160 : void ScriptCompiled(v8::Local<v8::debug::Script> script,
161 : bool has_compile_error) override;
162 : void BreakProgramRequested(v8::Local<v8::Context> paused_context,
163 : v8::Local<v8::Object> exec_state,
164 : v8::Local<v8::Value> break_points_hit) override;
165 : void ExceptionThrown(v8::Local<v8::Context> paused_context,
166 : v8::Local<v8::Object> exec_state,
167 : v8::Local<v8::Value> exception,
168 : v8::Local<v8::Value> promise, bool is_uncaught) override;
169 : bool IsFunctionBlackboxed(v8::Local<v8::debug::Script> script,
170 : const v8::debug::Location& start,
171 : const v8::debug::Location& end) override;
172 :
173 : int currentContextGroupId();
174 :
175 : v8::Isolate* m_isolate;
176 : V8InspectorImpl* m_inspector;
177 : int m_enableCount;
178 : bool m_breakpointsActivated;
179 : v8::Global<v8::Object> m_debuggerScript;
180 : v8::Global<v8::Context> m_debuggerContext;
181 : v8::Local<v8::Object> m_executionState;
182 : v8::Local<v8::Context> m_pausedContext;
183 : int m_ignoreScriptParsedEventsCounter;
184 : bool m_scheduledOOMBreak = false;
185 : int m_targetContextGroupId = 0;
186 : int m_pausedContextGroupId = 0;
187 :
188 : using AsyncTaskToStackTrace =
189 : protocol::HashMap<void*, std::weak_ptr<AsyncStackTrace>>;
190 : AsyncTaskToStackTrace m_asyncTaskStacks;
191 : AsyncTaskToStackTrace m_asyncTaskCreationStacks;
192 : protocol::HashSet<void*> m_recurringTasks;
193 : protocol::HashMap<void*, void*> m_parentTask;
194 :
195 : int m_maxAsyncCallStacks;
196 : int m_maxAsyncCallStackDepth;
197 :
198 : std::vector<void*> m_currentTasks;
199 : std::vector<std::shared_ptr<AsyncStackTrace>> m_currentAsyncParent;
200 : std::vector<std::shared_ptr<AsyncStackTrace>> m_currentAsyncCreation;
201 :
202 : void collectOldAsyncStacksIfNeeded();
203 : int m_asyncStacksCount = 0;
204 : // V8Debugger owns all the async stacks, while most of the other references
205 : // are weak, which allows to collect some stacks when there are too many.
206 : std::list<std::shared_ptr<AsyncStackTrace>> m_allAsyncStacks;
207 : std::map<int, std::weak_ptr<StackFrame>> m_framesCache;
208 :
209 : protocol::HashMap<V8DebuggerAgentImpl*, int> m_maxAsyncCallStackDepthMap;
210 : void* m_taskWithScheduledBreak = nullptr;
211 :
212 : std::unique_ptr<ScheduleStepIntoAsyncCallback> m_stepIntoAsyncCallback;
213 : bool m_breakRequested = false;
214 :
215 : v8::debug::ExceptionBreakState m_pauseOnExceptionsState;
216 :
217 : WasmTranslation m_wasmTranslation;
218 :
219 : DISALLOW_COPY_AND_ASSIGN(V8Debugger);
220 : };
221 :
222 : } // namespace v8_inspector
223 :
224 : #endif // V8_INSPECTOR_V8DEBUGGER_H_
|