blob: 04d1ad7c8927d05aad0b53f067f7fc92b239e7b3 [file] [log] [blame]
// Copyright 2015 The Chromium 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 V8DebuggerAgentImpl_h
#define V8DebuggerAgentImpl_h
#include "platform/inspector_protocol/InspectorProtocol.h"
#include "platform/v8_inspector/JavaScriptCallFrame.h"
#include "platform/v8_inspector/protocol/Debugger.h"
#include <vector>
namespace v8_inspector {
struct ScriptBreakpoint;
class JavaScriptCallFrame;
class PromiseTracker;
class V8Debugger;
class V8DebuggerScript;
class V8InspectorImpl;
class V8InspectorSessionImpl;
class V8Regex;
class V8StackTraceImpl;
namespace protocol = blink::protocol;
using blink::protocol::Maybe;
class V8DebuggerAgentImpl : public protocol::Debugger::Backend {
PROTOCOL_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 // V8DebuggerAgentImpl_h