// 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_V8_DEBUGGER_AGENT_IMPL_H_ #define V8_INSPECTOR_V8_DEBUGGER_AGENT_IMPL_H_ #include #include #include #include "src/base/macros.h" #include "src/debug/debug-interface.h" #include "src/debug/interface-types.h" #include "src/inspector/protocol/Debugger.h" #include "src/inspector/protocol/Forward.h" namespace v8_inspector { struct ScriptBreakpoint; class V8Debugger; class V8DebuggerScript; class V8InspectorImpl; class V8InspectorSessionImpl; class V8Regex; using protocol::Maybe; using protocol::Response; class V8DebuggerAgentImpl : public protocol::Debugger::Backend { public: enum BreakpointSource { UserBreakpointSource, DebugCommandBreakpointSource, MonitorCommandBreakpointSource }; V8DebuggerAgentImpl(V8InspectorSessionImpl*, protocol::FrontendChannel*, protocol::DictionaryValue* state); ~V8DebuggerAgentImpl() override; void restore(); // Part of the protocol. Response enable(Maybe maxScriptsCacheSize, String16* outDebuggerId) override; Response disable() override; Response setBreakpointsActive(bool active) override; Response setSkipAllPauses(bool skip) override; Response setBreakpointByUrl( int lineNumber, Maybe optionalURL, Maybe optionalURLRegex, Maybe optionalScriptHash, Maybe optionalColumnNumber, Maybe optionalCondition, String16*, std::unique_ptr>* locations) override; Response setBreakpoint( std::unique_ptr, Maybe optionalCondition, String16*, std::unique_ptr* actualLocation) override; Response setBreakpointOnFunctionCall(const String16& functionObjectId, Maybe optionalCondition, String16* outBreakpointId) override; Response setInstrumentationBreakpoint(const String16& instrumentation, String16* outBreakpointId) override; Response removeBreakpoint(const String16& breakpointId) override; Response continueToLocation(std::unique_ptr, Maybe targetCallFrames) override; Response getStackTrace( std::unique_ptr inStackTraceId, std::unique_ptr* outStackTrace) override; Response searchInContent( const String16& scriptId, const String16& query, Maybe optionalCaseSensitive, Maybe optionalIsRegex, std::unique_ptr>*) override; Response getPossibleBreakpoints( std::unique_ptr start, Maybe end, Maybe restrictToFunction, std::unique_ptr>* locations) override; Response setScriptSource( const String16& inScriptId, const String16& inScriptSource, Maybe dryRun, Maybe>* optOutCallFrames, Maybe* optOutStackChanged, Maybe* optOutAsyncStackTrace, Maybe* optOutAsyncStackTraceId, Maybe* optOutCompileError) override; Response restartFrame( const String16& callFrameId, std::unique_ptr>* newCallFrames, Maybe* asyncStackTrace, Maybe* asyncStackTraceId) override; Response getScriptSource(const String16& scriptId, String16* scriptSource) override; Response pause() override; Response resume() override; Response stepOver() override; Response stepInto(Maybe inBreakOnAsyncCall) override; Response stepOut() override; Response pauseOnAsyncCall(std::unique_ptr inParentStackTraceId) override; Response setPauseOnExceptions(const String16& pauseState) override; Response evaluateOnCallFrame( const String16& callFrameId, const String16& expression, Maybe objectGroup, Maybe includeCommandLineAPI, Maybe silent, Maybe returnByValue, Maybe generatePreview, Maybe throwOnSideEffect, Maybe timeout, std::unique_ptr* result, Maybe*) override; Response setVariableValue( int scopeNumber, const String16& variableName, std::unique_ptr newValue, const String16& callFrame) override; Response setReturnValue( std::unique_ptr newValue) override; Response setAsyncCallStackDepth(int depth) override; Response setBlackboxPatterns( std::unique_ptr> patterns) override; Response setBlackboxedRanges( const String16& scriptId, std::unique_ptr> positions) override; bool enabled() const { return m_enabled; } void setBreakpointFor(v8::Local function, v8::Local condition, BreakpointSource source); void removeBreakpointFor(v8::Local function, BreakpointSource source); void schedulePauseOnNextStatement( const String16& breakReason, std::unique_ptr data); void cancelPauseOnNextStatement(); void breakProgram(const String16& breakReason, std::unique_ptr data); void reset(); // Interface for V8InspectorImpl void didPause(int contextId, v8::Local exception, const std::vector& hitBreakpoints, v8::debug::ExceptionType exceptionType, bool isUncaught, bool isOOMBreak, bool isAssert); void didContinue(); void didParseSource(std::unique_ptr, bool success); bool isFunctionBlackboxed(const String16& scriptId, const v8::debug::Location& start, const v8::debug::Location& end); bool acceptsPause(bool isOOMBreak) const; void ScriptCollected(const V8DebuggerScript* script); v8::Isolate* isolate() { return m_isolate; } private: void enableImpl(); Response currentCallFrames( std::unique_ptr>*); std::unique_ptr currentAsyncStackTrace(); std::unique_ptr currentExternalStackTrace(); std::unique_ptr currentScheduledAsyncCall(); void setPauseOnExceptionsImpl(int); std::unique_ptr setBreakpointImpl( const String16& breakpointId, const String16& scriptId, const String16& condition, int lineNumber, int columnNumber); void setBreakpointImpl(const String16& breakpointId, v8::Local function, v8::Local condition); void removeBreakpointImpl(const String16& breakpointId); void clearBreakDetails(); void internalSetAsyncCallStackDepth(int); void increaseCachedSkipStackGeneration(); Response setBlackboxPattern(const String16& pattern); void resetBlackboxedStateCache(); bool isPaused() const; void setScriptInstrumentationBreakpointIfNeeded(V8DebuggerScript* script); using ScriptsMap = std::unordered_map>; using BreakpointIdToDebuggerBreakpointIdsMap = std::unordered_map>; using DebuggerBreakpointIdToBreakpointIdMap = std::unordered_map; 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; ScriptsMap m_scripts; BreakpointIdToDebuggerBreakpointIdsMap m_breakpointIdToDebuggerBreakpointIds; DebuggerBreakpointIdToBreakpointIdMap m_debuggerBreakpointIdToBreakpointId; std::unordered_map> m_breakpointsOnScriptRun; size_t m_maxScriptCacheSize = 0; size_t m_cachedScriptSize = 0; std::deque m_cachedScriptIds; using BreakReason = std::pair>; std::vector m_breakReason; void pushBreakDetails( const String16& breakReason, std::unique_ptr breakAuxData); void popBreakDetails(); bool m_skipAllPauses = false; bool m_breakpointsActive = false; std::unique_ptr m_blackboxPattern; std::unordered_map>> m_blackboxedPositions; DISALLOW_COPY_AND_ASSIGN(V8DebuggerAgentImpl); }; } // namespace v8_inspector #endif // V8_INSPECTOR_V8_DEBUGGER_AGENT_IMPL_H_