chromium/v8/src/inspector/v8-debugger-agent-impl.cc

// 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.

#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[] =;

}  // namespace DebuggerAgentState

static const char kBacktraceObjectGroup[] =;
static const char kDebuggerNotEnabled[] =;
static const char kDebuggerNotPaused[] =;

static const size_t kBreakpointHintMaxLength =;
static const intptr_t kBreakpointHintMaxSearchOffset =;
// Limit the number of breakpoints returned, as we otherwise may exceed
// the maximum length of a message in mojo (see https://crbug.com/1105172).
static const size_t kMaxNumBreakpoints =;

#if V8_ENABLE_WEBASSEMBLY
// TODO(1099680): getScriptSource and getWasmBytecode return Wasm wire bytes
// as protocol::Binary, which is encoded as JSON string in the communication
// to the DevTools front-end and hence leads to either crashing the renderer
// that is being debugged or the renderer that's running the front-end if we
// allow arbitrarily big Wasm byte sequences here. Ideally we would find a
// different way to transfer the wire bytes (middle- to long-term), but as a
// short-term solution, we should at least not crash.
static constexpr size_t kWasmBytecodeMaxLength =;
static constexpr const char kWasmBytecodeExceedsTransferLimit[] =;
#endif  // V8_ENABLE_WEBASSEMBLY

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) {}
}  // namespace

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 {};

}  // namespace

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) {}
}  // namespace

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  // V8_ENABLE_WEBASSEMBLY

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() {}
}  // namespace v8_inspector