#include "src/inspector/v8-debugger-agent-impl.h"
#include <algorithm>
#include <memory>
#include "../../third_party/inspector_protocol/crdtp/json.h"
#include "include/v8-context.h"
#include "include/v8-function.h"
#include "include/v8-inspector.h"
#include "include/v8-microtask-queue.h"
#include "src/base/safe_conversions.h"
#include "src/debug/debug-interface.h"
#include "src/inspector/crc32.h"
#include "src/inspector/injected-script.h"
#include "src/inspector/inspected-context.h"
#include "src/inspector/protocol/Debugger.h"
#include "src/inspector/protocol/Protocol.h"
#include "src/inspector/remote-object-id.h"
#include "src/inspector/search-util.h"
#include "src/inspector/string-util.h"
#include "src/inspector/v8-debugger-script.h"
#include "src/inspector/v8-debugger.h"
#include "src/inspector/v8-inspector-impl.h"
#include "src/inspector/v8-inspector-session-impl.h"
#include "src/inspector/v8-regex.h"
#include "src/inspector/v8-runtime-agent-impl.h"
#include "src/inspector/v8-stack-trace-impl.h"
#include "src/inspector/v8-value-utils.h"
namespace v8_inspector {
Array;
Maybe;
BreakpointId;
CallFrame;
Scope;
ExceptionDetails;
RemoteObject;
ScriptId;
InstrumentationEnum;
namespace DebuggerAgentState {
static const char pauseOnExceptionsState[] = …;
static const char asyncCallStackDepth[] = …;
static const char blackboxPattern[] = …;
static const char debuggerEnabled[] = …;
static const char breakpointsActiveWhenEnabled[] = …;
static const char skipAllPauses[] = …;
static const char breakpointsByRegex[] = …;
static const char breakpointsByUrl[] = …;
static const char breakpointsByScriptHash[] = …;
static const char breakpointHints[] = …;
static const char breakpointHintText[] = …;
static const char breakpointHintPrefixHash[] = …;
static const char breakpointHintPrefixLength[] = …;
static const char instrumentationBreakpoints[] = …;
static const char maxScriptCacheSize[] = …;
}
static const char kBacktraceObjectGroup[] = …;
static const char kDebuggerNotEnabled[] = …;
static const char kDebuggerNotPaused[] = …;
static const size_t kBreakpointHintMaxLength = …;
static const intptr_t kBreakpointHintMaxSearchOffset = …;
static const size_t kMaxNumBreakpoints = …;
#if V8_ENABLE_WEBASSEMBLY
static constexpr size_t kWasmBytecodeMaxLength = …;
static constexpr const char kWasmBytecodeExceedsTransferLimit[] = …;
#endif
namespace {
enum class BreakpointType { … };
String16 generateBreakpointId(BreakpointType type,
const String16& scriptSelector, int lineNumber,
int columnNumber) { … }
String16 generateBreakpointId(BreakpointType type,
v8::Local<v8::Function> function) { … }
String16 generateInstrumentationBreakpointId(const String16& instrumentation) { … }
bool parseBreakpointId(const String16& breakpointId, BreakpointType* type,
String16* scriptSelector = nullptr,
int* lineNumber = nullptr, int* columnNumber = nullptr) { … }
bool positionComparator(const std::pair<int, int>& a,
const std::pair<int, int>& b) { … }
std::unique_ptr<protocol::DictionaryValue> breakpointHint(
const V8DebuggerScript& script, int breakpointLineNumber,
int breakpointColumnNumber, int actualLineNumber, int actualColumnNumber) { … }
void adjustBreakpointLocation(const V8DebuggerScript& script,
const protocol::DictionaryValue* hintObject,
int* lineNumber, int* columnNumber) { … }
String16 breakLocationType(v8::debug::BreakLocationType type) { … }
String16 scopeType(v8::debug::ScopeIterator::ScopeType type) { … }
Response buildScopes(v8::Isolate* isolate, v8::debug::ScopeIterator* iterator,
InjectedScript* injectedScript,
std::unique_ptr<Array<Scope>>* scopes) { … }
protocol::DictionaryValue* getOrCreateObject(protocol::DictionaryValue* object,
const String16& key) { … }
Response isValidPosition(protocol::Debugger::ScriptPosition* position) { … }
Response isValidRangeOfPositions(std::vector<std::pair<int, int>>& positions) { … }
bool hitBreakReasonEncodedAsOther(v8::debug::BreakReasons breakReasons) { … }
}
V8DebuggerAgentImpl::V8DebuggerAgentImpl(
V8InspectorSessionImpl* session, protocol::FrontendChannel* frontendChannel,
protocol::DictionaryValue* state)
: … { … }
V8DebuggerAgentImpl::~V8DebuggerAgentImpl() = default;
void V8DebuggerAgentImpl::enableImpl() { … }
Response V8DebuggerAgentImpl::enable(Maybe<double> maxScriptsCacheSize,
String16* outDebuggerId) { … }
Response V8DebuggerAgentImpl::disable() { … }
void V8DebuggerAgentImpl::restore() { … }
Response V8DebuggerAgentImpl::setBreakpointsActive(bool active) { … }
Response V8DebuggerAgentImpl::setSkipAllPauses(bool skip) { … }
namespace {
class Matcher { … };
}
Response V8DebuggerAgentImpl::setBreakpointByUrl(
int lineNumber, Maybe<String16> optionalURL,
Maybe<String16> optionalURLRegex, Maybe<String16> optionalScriptHash,
Maybe<int> optionalColumnNumber, Maybe<String16> optionalCondition,
String16* outBreakpointId,
std::unique_ptr<protocol::Array<protocol::Debugger::Location>>* locations) { … }
Response V8DebuggerAgentImpl::setBreakpoint(
std::unique_ptr<protocol::Debugger::Location> location,
Maybe<String16> optionalCondition, String16* outBreakpointId,
std::unique_ptr<protocol::Debugger::Location>* actualLocation) { … }
Response V8DebuggerAgentImpl::setBreakpointOnFunctionCall(
const String16& functionObjectId, Maybe<String16> optionalCondition,
String16* outBreakpointId) { … }
Response V8DebuggerAgentImpl::setInstrumentationBreakpoint(
const String16& instrumentation, String16* outBreakpointId) { … }
Response V8DebuggerAgentImpl::removeBreakpoint(const String16& breakpointId) { … }
void V8DebuggerAgentImpl::removeBreakpointImpl(
const String16& breakpointId,
const std::vector<V8DebuggerScript*>& scripts) { … }
Response V8DebuggerAgentImpl::getPossibleBreakpoints(
std::unique_ptr<protocol::Debugger::Location> start,
Maybe<protocol::Debugger::Location> end, Maybe<bool> restrictToFunction,
std::unique_ptr<protocol::Array<protocol::Debugger::BreakLocation>>*
locations) { … }
Response V8DebuggerAgentImpl::continueToLocation(
std::unique_ptr<protocol::Debugger::Location> location,
Maybe<String16> targetCallFrames) { … }
Response V8DebuggerAgentImpl::getStackTrace(
std::unique_ptr<protocol::Runtime::StackTraceId> inStackTraceId,
std::unique_ptr<protocol::Runtime::StackTrace>* outStackTrace) { … }
bool V8DebuggerAgentImpl::isFunctionBlackboxed(const String16& scriptId,
const v8::debug::Location& start,
const v8::debug::Location& end) { … }
bool V8DebuggerAgentImpl::shouldBeSkipped(const String16& scriptId, int line,
int column) { … }
bool V8DebuggerAgentImpl::acceptsPause(bool isOOMBreak) const { … }
std::unique_ptr<protocol::Debugger::Location>
V8DebuggerAgentImpl::setBreakpointImpl(const String16& breakpointId,
const String16& scriptId,
const String16& condition,
int lineNumber, int columnNumber) { … }
void V8DebuggerAgentImpl::setBreakpointImpl(const String16& breakpointId,
v8::Local<v8::Function> function,
v8::Local<v8::String> condition) { … }
Response V8DebuggerAgentImpl::searchInContent(
const String16& scriptId, const String16& query,
Maybe<bool> optionalCaseSensitive, Maybe<bool> optionalIsRegex,
std::unique_ptr<Array<protocol::Debugger::SearchMatch>>* results) { … }
namespace {
const char* buildStatus(v8::debug::LiveEditResult::Status status) { … }
}
Response V8DebuggerAgentImpl::setScriptSource(
const String16& scriptId, const String16& newContent, Maybe<bool> dryRun,
Maybe<bool> allowTopFrameEditing,
Maybe<protocol::Array<protocol::Debugger::CallFrame>>* newCallFrames,
Maybe<bool>* stackChanged,
Maybe<protocol::Runtime::StackTrace>* asyncStackTrace,
Maybe<protocol::Runtime::StackTraceId>* asyncStackTraceId, String16* status,
Maybe<protocol::Runtime::ExceptionDetails>* optOutCompileError) { … }
Response V8DebuggerAgentImpl::restartFrame(
const String16& callFrameId, Maybe<String16> mode,
std::unique_ptr<Array<CallFrame>>* newCallFrames,
Maybe<protocol::Runtime::StackTrace>* asyncStackTrace,
Maybe<protocol::Runtime::StackTraceId>* asyncStackTraceId) { … }
Response V8DebuggerAgentImpl::getScriptSource(
const String16& scriptId, String16* scriptSource,
Maybe<protocol::Binary>* bytecode) { … }
struct DisassemblyChunk { … };
class DisassemblyCollectorImpl final : public v8::debug::DisassemblyCollector { … };
Response V8DebuggerAgentImpl::disassembleWasmModule(
const String16& in_scriptId, Maybe<String16>* out_streamId,
int* out_totalNumberOfLines,
std::unique_ptr<protocol::Array<int>>* out_functionBodyOffsets,
std::unique_ptr<protocol::Debugger::WasmDisassemblyChunk>* out_chunk) { … }
Response V8DebuggerAgentImpl::nextWasmDisassemblyChunk(
const String16& in_streamId,
std::unique_ptr<protocol::Debugger::WasmDisassemblyChunk>* out_chunk) { … }
Response V8DebuggerAgentImpl::getWasmBytecode(const String16& scriptId,
protocol::Binary* bytecode) { … }
void V8DebuggerAgentImpl::pushBreakDetails(
const String16& breakReason,
std::unique_ptr<protocol::DictionaryValue> breakAuxData) { … }
void V8DebuggerAgentImpl::popBreakDetails() { … }
void V8DebuggerAgentImpl::clearBreakDetails() { … }
void V8DebuggerAgentImpl::schedulePauseOnNextStatement(
const String16& breakReason,
std::unique_ptr<protocol::DictionaryValue> data) { … }
void V8DebuggerAgentImpl::cancelPauseOnNextStatement() { … }
Response V8DebuggerAgentImpl::pause() { … }
Response V8DebuggerAgentImpl::resume(Maybe<bool> terminateOnResume) { … }
Response V8DebuggerAgentImpl::stepOver(
Maybe<protocol::Array<protocol::Debugger::LocationRange>> inSkipList) { … }
Response V8DebuggerAgentImpl::stepInto(
Maybe<bool> inBreakOnAsyncCall,
Maybe<protocol::Array<protocol::Debugger::LocationRange>> inSkipList) { … }
Response V8DebuggerAgentImpl::stepOut() { … }
Response V8DebuggerAgentImpl::pauseOnAsyncCall(
std::unique_ptr<protocol::Runtime::StackTraceId> inParentStackTraceId) { … }
Response V8DebuggerAgentImpl::setPauseOnExceptions(
const String16& stringPauseState) { … }
void V8DebuggerAgentImpl::setPauseOnExceptionsImpl(int pauseState) { … }
Response V8DebuggerAgentImpl::evaluateOnCallFrame(
const String16& callFrameId, const String16& expression,
Maybe<String16> objectGroup, Maybe<bool> includeCommandLineAPI,
Maybe<bool> silent, Maybe<bool> returnByValue, Maybe<bool> generatePreview,
Maybe<bool> throwOnSideEffect, Maybe<double> timeout,
std::unique_ptr<RemoteObject>* result,
Maybe<protocol::Runtime::ExceptionDetails>* exceptionDetails) { … }
Response V8DebuggerAgentImpl::setVariableValue(
int scopeNumber, const String16& variableName,
std::unique_ptr<protocol::Runtime::CallArgument> newValueArgument,
const String16& callFrameId) { … }
Response V8DebuggerAgentImpl::setReturnValue(
std::unique_ptr<protocol::Runtime::CallArgument> protocolNewValue) { … }
Response V8DebuggerAgentImpl::setAsyncCallStackDepth(int depth) { … }
Response V8DebuggerAgentImpl::setBlackboxPatterns(
std::unique_ptr<protocol::Array<String16>> patterns) { … }
Response V8DebuggerAgentImpl::setBlackboxPattern(const String16& pattern) { … }
void V8DebuggerAgentImpl::resetBlackboxedStateCache() { … }
Response V8DebuggerAgentImpl::setBlackboxedRanges(
const String16& scriptId,
std::unique_ptr<protocol::Array<protocol::Debugger::ScriptPosition>>
inPositions) { … }
Response V8DebuggerAgentImpl::currentCallFrames(
std::unique_ptr<Array<CallFrame>>* result) { … }
std::unique_ptr<protocol::Runtime::StackTrace>
V8DebuggerAgentImpl::currentAsyncStackTrace() { … }
std::unique_ptr<protocol::Runtime::StackTraceId>
V8DebuggerAgentImpl::currentExternalStackTrace() { … }
bool V8DebuggerAgentImpl::isPaused() const { … }
static String16 getScriptLanguage(const V8DebuggerScript& script) { … }
#if V8_ENABLE_WEBASSEMBLY
static const char* getDebugSymbolTypeName(
v8::debug::WasmScript::DebugSymbolsType type) { … }
static std::unique_ptr<protocol::Debugger::DebugSymbols> getDebugSymbols(
const V8DebuggerScript& script) { … }
#endif
void V8DebuggerAgentImpl::didParseSource(
std::unique_ptr<V8DebuggerScript> script, bool success) { … }
void V8DebuggerAgentImpl::setScriptInstrumentationBreakpointIfNeeded(
V8DebuggerScript* scriptRef) { … }
void V8DebuggerAgentImpl::didPauseOnInstrumentation(
v8::debug::BreakpointId instrumentationId) { … }
void V8DebuggerAgentImpl::didPause(
int contextId, v8::Local<v8::Value> exception,
const std::vector<v8::debug::BreakpointId>& hitBreakpoints,
v8::debug::ExceptionType exceptionType, bool isUncaught,
v8::debug::BreakReasons breakReasons) { … }
void V8DebuggerAgentImpl::didContinue() { … }
void V8DebuggerAgentImpl::breakProgram(
const String16& breakReason,
std::unique_ptr<protocol::DictionaryValue> data) { … }
void V8DebuggerAgentImpl::setBreakpointFor(v8::Local<v8::Function> function,
v8::Local<v8::String> condition,
BreakpointSource source) { … }
void V8DebuggerAgentImpl::removeBreakpointFor(v8::Local<v8::Function> function,
BreakpointSource source) { … }
void V8DebuggerAgentImpl::reset() { … }
void V8DebuggerAgentImpl::ScriptCollected(const V8DebuggerScript* script) { … }
Response V8DebuggerAgentImpl::processSkipList(
protocol::Array<protocol::Debugger::LocationRange>& skipList) { … }
void V8DebuggerAgentImpl::stop() { … }
}