blob: 45744b00d35bdd646a3bcc9433e050c683821d60 [file] [log] [blame]
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_INSPECTOR_V8DEBUGGERAGENTIMPL_H_
#define V8_INSPECTOR_V8DEBUGGERAGENTIMPL_H_
#include "src/inspector/Allocator.h"
#include "src/inspector/JavaScriptCallFrame.h"
#include "src/inspector/protocol/Debugger.h"
#include "src/inspector/protocol/Forward.h"
#include <vector>
namespace v8_inspector {
struct ScriptBreakpoint;
class JavaScriptCallFrame;
class PromiseTracker;
class V8Debugger;
class V8DebuggerScript;
class V8InspectorImpl;
class V8InspectorSessionImpl;
class V8Regex;
class V8StackTraceImpl;
using protocol::ErrorString;
using protocol::Maybe;
class V8DebuggerAgentImpl : public protocol::Debugger::Backend {
V8_INSPECTOR_DISALLOW_COPY(V8DebuggerAgentImpl);
public:
enum SkipPauseRequest {
RequestNoSkip,
RequestContinue,
RequestStepInto,
RequestStepOut,
RequestStepFrame
};
enum BreakpointSource {
UserBreakpointSource,
DebugCommandBreakpointSource,
MonitorCommandBreakpointSource
};
V8DebuggerAgentImpl(V8InspectorSessionImpl*, protocol::FrontendChannel*,
protocol::DictionaryValue* state);
~V8DebuggerAgentImpl() override;
void restore();
// Part of the protocol.
void enable(ErrorString*) override;
void disable(ErrorString*) override;
void setBreakpointsActive(ErrorString*, bool active) override;
void setSkipAllPauses(ErrorString*, bool skip) override;
void setBreakpointByUrl(
ErrorString*, int lineNumber, const Maybe<String16>& optionalURL,
const Maybe<String16>& optionalURLRegex,
const Maybe<int>& optionalColumnNumber,
const Maybe<String16>& optionalCondition, String16*,
std::unique_ptr<protocol::Array<protocol::Debugger::Location>>* locations)
override;
void setBreakpoint(
ErrorString*, std::unique_ptr<protocol::Debugger::Location>,
const Maybe<String16>& optionalCondition, String16*,
std::unique_ptr<protocol::Debugger::Location>* actualLocation) override;
void removeBreakpoint(ErrorString*, const String16& breakpointId) override;
void continueToLocation(
ErrorString*, std::unique_ptr<protocol::Debugger::Location>) override;
void searchInContent(
ErrorString*, const String16& scriptId, const String16& query,
const Maybe<bool>& optionalCaseSensitive,
const Maybe<bool>& optionalIsRegex,
std::unique_ptr<protocol::Array<protocol::Debugger::SearchMatch>>*)
override;
void setScriptSource(
ErrorString*, const String16& inScriptId, const String16& inScriptSource,
const Maybe<bool>& dryRun,
Maybe<protocol::Array<protocol::Debugger::CallFrame>>* optOutCallFrames,
Maybe<bool>* optOutStackChanged,
Maybe<protocol::Runtime::StackTrace>* optOutAsyncStackTrace,
Maybe<protocol::Runtime::ExceptionDetails>* optOutCompileError) override;
void restartFrame(
ErrorString*, const String16& callFrameId,
std::unique_ptr<protocol::Array<protocol::Debugger::CallFrame>>*
newCallFrames,
Maybe<protocol::Runtime::StackTrace>* asyncStackTrace) override;
void getScriptSource(ErrorString*, const String16& scriptId,
String16* scriptSource) override;
void pause(ErrorString*) override;
void resume(ErrorString*) override;
void stepOver(ErrorString*) override;
void stepInto(ErrorString*) override;
void stepOut(ErrorString*) override;
void setPauseOnExceptions(ErrorString*, const String16& pauseState) override;
void evaluateOnCallFrame(
ErrorString*, const String16& callFrameId, const String16& expression,
const Maybe<String16>& objectGroup,
const Maybe<bool>& includeCommandLineAPI, const Maybe<bool>& silent,
const Maybe<bool>& returnByValue, const Maybe<bool>& generatePreview,
std::unique_ptr<protocol::Runtime::RemoteObject>* result,
Maybe<protocol::Runtime::ExceptionDetails>*) override;
void setVariableValue(
ErrorString*, int scopeNumber, const String16& variableName,
std::unique_ptr<protocol::Runtime::CallArgument> newValue,
const String16& callFrame) override;
void setAsyncCallStackDepth(ErrorString*, int depth) override;
void setBlackboxPatterns(
ErrorString*,
std::unique_ptr<protocol::Array<String16>> patterns) override;
void setBlackboxedRanges(
ErrorString*, const String16& scriptId,
std::unique_ptr<protocol::Array<protocol::Debugger::ScriptPosition>>
positions) override;
bool enabled();
void setBreakpointAt(const String16& scriptId, int lineNumber,
int columnNumber, BreakpointSource,
const String16& condition = String16());
void removeBreakpointAt(const String16& scriptId, int lineNumber,
int columnNumber, BreakpointSource);
void schedulePauseOnNextStatement(
const String16& breakReason,
std::unique_ptr<protocol::DictionaryValue> data);
void cancelPauseOnNextStatement();
void breakProgram(const String16& breakReason,
std::unique_ptr<protocol::DictionaryValue> data);
void breakProgramOnException(const String16& breakReason,
std::unique_ptr<protocol::DictionaryValue> data);
void reset();
// Interface for V8InspectorImpl
SkipPauseRequest didPause(v8::Local<v8::Context>,
v8::Local<v8::Value> exception,
const std::vector<String16>& hitBreakpoints,
bool isPromiseRejection);
void didContinue();
void didParseSource(std::unique_ptr<V8DebuggerScript>, bool success);
void willExecuteScript(int scriptId);
void didExecuteScript();
v8::Isolate* isolate() { return m_isolate; }
private:
bool checkEnabled(ErrorString*);
void enable();
SkipPauseRequest shouldSkipExceptionPause(JavaScriptCallFrame* topCallFrame);
SkipPauseRequest shouldSkipStepPause(JavaScriptCallFrame* topCallFrame);
void schedulePauseOnNextStatementIfSteppingInto();
std::unique_ptr<protocol::Array<protocol::Debugger::CallFrame>>
currentCallFrames(ErrorString*);
std::unique_ptr<protocol::Runtime::StackTrace> currentAsyncStackTrace();
void changeJavaScriptRecursionLevel(int step);
void setPauseOnExceptionsImpl(ErrorString*, int);
std::unique_ptr<protocol::Debugger::Location> resolveBreakpoint(
const String16& breakpointId, const String16& scriptId,
const ScriptBreakpoint&, BreakpointSource);
void removeBreakpoint(const String16& breakpointId);
bool assertPaused(ErrorString*);
void clearBreakDetails();
bool isCurrentCallStackEmptyOrBlackboxed();
bool isTopPausedCallFrameBlackboxed();
bool isCallFrameWithUnknownScriptOrBlackboxed(JavaScriptCallFrame*);
void internalSetAsyncCallStackDepth(int);
void increaseCachedSkipStackGeneration();
bool setBlackboxPattern(ErrorString*, const String16& pattern);
using ScriptsMap =
protocol::HashMap<String16, std::unique_ptr<V8DebuggerScript>>;
using BreakpointIdToDebuggerBreakpointIdsMap =
protocol::HashMap<String16, std::vector<String16>>;
using DebugServerBreakpointToBreakpointIdAndSourceMap =
protocol::HashMap<String16, std::pair<String16, BreakpointSource>>;
using MuteBreakpoins = protocol::HashMap<String16, std::pair<String16, int>>;
enum DebuggerStep { NoStep = 0, StepInto, StepOver, StepOut };
V8InspectorImpl* m_inspector;
V8Debugger* m_debugger;
V8InspectorSessionImpl* m_session;
bool m_enabled;
protocol::DictionaryValue* m_state;
protocol::Debugger::Frontend m_frontend;
v8::Isolate* m_isolate;
v8::Global<v8::Context> m_pausedContext;
JavaScriptCallFrames m_pausedCallFrames;
ScriptsMap m_scripts;
BreakpointIdToDebuggerBreakpointIdsMap m_breakpointIdToDebuggerBreakpointIds;
DebugServerBreakpointToBreakpointIdAndSourceMap m_serverBreakpoints;
String16 m_continueToLocationBreakpointId;
String16 m_breakReason;
std::unique_ptr<protocol::DictionaryValue> m_breakAuxData;
DebuggerStep m_scheduledDebuggerStep;
bool m_skipNextDebuggerStepOut;
bool m_javaScriptPauseScheduled;
bool m_steppingFromFramework;
bool m_pausingOnNativeEvent;
int m_skippedStepFrameCount;
int m_recursionLevelForStepOut;
int m_recursionLevelForStepFrame;
bool m_skipAllPauses;
std::unique_ptr<V8Regex> m_blackboxPattern;
protocol::HashMap<String16, std::vector<std::pair<int, int>>>
m_blackboxedPositions;
};
} // namespace v8_inspector
#endif // V8_INSPECTOR_V8DEBUGGERAGENTIMPL_H_