void InspectorDebuggerAgent::reset() { scriptDebugServer().clearBreakpoints(); m_scripts.clear(); m_breakpointIdToDebugServerBreakpointIds.clear(); if (m_frontend) m_frontend->globalObjectCleared(); }
void InspectorDebuggerAgent::scriptExecutionBlockedByCSP(const String& directiveText) { if (scriptDebugServer().pauseOnExceptionsState() != ScriptDebugServer::DontPauseOnExceptions) { RefPtr<InspectorObject> directive = InspectorObject::create(); directive->setString("directiveText", directiveText); breakProgram(InspectorFrontend::Debugger::Reason::CSPViolation, directive.release()); } }
void InspectorDebuggerAgent::stepInto(ErrorString* errorString) { if (!assertPaused(errorString)) return; m_injectedScriptManager->releaseObjectGroup(InspectorDebuggerAgent::backtraceObjectGroup); scriptDebugServer().stepIntoStatement(); m_listener->stepInto(); }
void InspectorDebuggerAgent::pause(ErrorString*) { if (m_javaScriptPauseScheduled) return; clearBreakDetails(); scriptDebugServer().setPauseOnNextStatement(true); m_javaScriptPauseScheduled = true; }
void InspectorDebuggerAgent::schedulePauseOnNextStatement(InspectorFrontend::Debugger::Reason::Enum breakReason, PassRefPtr<InspectorObject> data) { if (m_javaScriptPauseScheduled) return; m_breakReason = breakReason; m_breakAuxData = data; scriptDebugServer().setPauseOnNextStatement(true); }
void InspectorDebuggerAgent::schedulePauseOnNextStatement(DebuggerEventType type, PassRefPtr<InspectorValue> data) { if (m_javaScriptPauseScheduled) return; m_breakProgramDetails = InspectorObject::create(); m_breakProgramDetails->setNumber("eventType", type); m_breakProgramDetails->setValue("eventData", data); scriptDebugServer().setPauseOnNextStatement(true); }
void InspectorDebuggerAgent::continueToLocation(ErrorString* errorString, const RefPtr<InspectorObject>& location) { if (!m_continueToLocationBreakpointId.isEmpty()) { scriptDebugServer().removeBreakpoint(m_continueToLocationBreakpointId); m_continueToLocationBreakpointId = ""; } String scriptId; int lineNumber; int columnNumber; if (!parseLocation(errorString, location, &scriptId, &lineNumber, &columnNumber)) return; ScriptBreakpoint breakpoint(lineNumber, columnNumber, "", false); m_continueToLocationBreakpointId = scriptDebugServer().setBreakpoint(scriptId, breakpoint, &lineNumber, &columnNumber); resume(errorString); }
void InspectorDebuggerAgent::schedulePauseOnNextStatement(DebuggerFrontendDispatcher::Reason breakReason, RefPtr<InspectorObject>&& data) { if (m_javaScriptPauseScheduled) return; m_breakReason = breakReason; m_breakAuxData = WTF::move(data); scriptDebugServer().setPauseOnNextStatement(true); }
void InspectorDebuggerAgent::setPauseOnExceptions(ErrorString& errorString, const String& stringPauseState) { JSC::Debugger::PauseOnExceptionsState pauseState; if (stringPauseState == "none") pauseState = JSC::Debugger::DontPauseOnExceptions; else if (stringPauseState == "all") pauseState = JSC::Debugger::PauseOnAllExceptions; else if (stringPauseState == "uncaught") pauseState = JSC::Debugger::PauseOnUncaughtExceptions; else { errorString = ASCIILiteral("Unknown pause on exceptions mode: ") + stringPauseState; return; } scriptDebugServer().setPauseOnExceptionsState(static_cast<JSC::Debugger::PauseOnExceptionsState>(pauseState)); if (scriptDebugServer().pauseOnExceptionsState() != pauseState) errorString = ASCIILiteral("Internal error. Could not change pause on exceptions state"); }
void InspectorDebuggerAgent::stepOut(ErrorString* errorString, const String* callFrameId) { if (!assertPaused(errorString)) return; ScriptValue frame = resolveCallFrame(errorString, callFrameId); if (!errorString->isEmpty()) return; m_injectedScriptManager->releaseObjectGroup(InspectorDebuggerAgent::backtraceObjectGroup); scriptDebugServer().stepOutOfFunction(frame); }
void InspectorDebuggerAgent::stepInto(ErrorString& errorString) { if (!assertPaused(errorString)) return; scriptDebugServer().stepIntoStatement(); if (m_listener) m_listener->stepInto(); }
void InspectorDebuggerAgent::enable() { m_instrumentingAgents->setInspectorDebuggerAgent(this); // FIXME(WK44513): breakpoints activated flag should be synchronized between all front-ends scriptDebugServer().setBreakpointsActivated(true); startListeningScriptDebugServer(); if (m_listener) m_listener->debuggerWasEnabled(); }
void InspectorDebuggerAgent::removeBreakpoint(ErrorString*, const String& breakpointId) { m_javaScriptBreakpoints.remove(breakpointId); BreakpointIdToDebugServerBreakpointIdsMap::iterator debugServerBreakpointIdsIterator = m_breakpointIdToDebugServerBreakpointIds.find(breakpointId); if (debugServerBreakpointIdsIterator == m_breakpointIdToDebugServerBreakpointIds.end()) return; for (size_t i = 0; i < debugServerBreakpointIdsIterator->value.size(); ++i) scriptDebugServer().removeBreakpoint(debugServerBreakpointIdsIterator->value[i]); m_breakpointIdToDebugServerBreakpointIds.remove(debugServerBreakpointIdsIterator); }
void InspectorDebuggerAgent::setScriptSource(ErrorString* error, const String& scriptId, const String& newContent, const bool* const preview, RefPtr<Array<TypeBuilder::Debugger::CallFrame>>& newCallFrames, RefPtr<InspectorObject>& result) { bool previewOnly = preview && *preview; ScriptObject resultObject; if (!scriptDebugServer().setScriptSource(scriptId, newContent, previewOnly, error, &m_currentCallStack, &resultObject)) return; newCallFrames = currentCallFrames(); RefPtr<InspectorObject> object = scriptToInspectorObject(resultObject); if (object) result = object; }
void InspectorDebuggerAgent::removeBreakpoint(const String& breakpointId) { BreakpointIdToDebugServerBreakpointIdsMap::iterator debugServerBreakpointIdsIterator = m_breakpointIdToDebugServerBreakpointIds.find(breakpointId); if (debugServerBreakpointIdsIterator == m_breakpointIdToDebugServerBreakpointIds.end()) return; for (size_t i = 0; i < debugServerBreakpointIdsIterator->value.size(); ++i) { const String& debugServerBreakpointId = debugServerBreakpointIdsIterator->value[i]; scriptDebugServer().removeBreakpoint(debugServerBreakpointId); m_serverBreakpoints.remove(debugServerBreakpointId); } m_breakpointIdToDebugServerBreakpointIds.remove(debugServerBreakpointIdsIterator); }
void InspectorDebuggerAgent::restartFrame(ErrorString* errorString, const String& callFrameId, RefPtr<Array<TypeBuilder::Debugger::CallFrame> >& newCallFrames, RefPtr<InspectorObject>& result) { InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(callFrameId); if (injectedScript.hasNoValue()) { *errorString = "Inspected frame has gone"; return; } injectedScript.restartFrame(errorString, m_currentCallStack, callFrameId, &result); scriptDebugServer().updateCallStack(&m_currentCallStack); newCallFrames = currentCallFrames(); }
void InspectorDebuggerAgent::disable() { m_state->setObject(DebuggerAgentState::javaScriptBreakpoints, InspectorObject::create()); m_instrumentingAgents->setInspectorDebuggerAgent(0); stopListeningScriptDebugServer(); scriptDebugServer().clearBreakpoints(); clear(); if (m_listener) m_listener->debuggerWasDisabled(); }
void InspectorDebuggerAgent::enable() { if (m_enabled) return; scriptDebugServer().setBreakpointsActivated(true); startListeningScriptDebugServer(); if (m_listener) m_listener->debuggerWasEnabled(); m_enabled = true; }
JSGlobalObjectInspectorController::JSGlobalObjectInspectorController(JSGlobalObject& globalObject) : m_globalObject(globalObject) , m_injectedScriptManager(std::make_unique<InjectedScriptManager>(*this, InjectedScriptHost::create())) , m_inspectorFrontendChannel(nullptr) , m_includeNativeCallStackWithExceptions(true) { auto runtimeAgent = std::make_unique<JSGlobalObjectRuntimeAgent>(m_injectedScriptManager.get(), m_globalObject); auto consoleAgent = std::make_unique<JSGlobalObjectConsoleAgent>(m_injectedScriptManager.get()); auto debuggerAgent = std::make_unique<JSGlobalObjectDebuggerAgent>(m_injectedScriptManager.get(), m_globalObject, consoleAgent.get()); auto profilerAgent = std::make_unique<JSGlobalObjectProfilerAgent>(m_globalObject); m_consoleAgent = consoleAgent.get(); m_consoleClient = std::make_unique<JSConsoleClient>(m_consoleAgent, profilerAgent.get()); runtimeAgent->setScriptDebugServer(&debuggerAgent->scriptDebugServer()); profilerAgent->setScriptDebugServer(&debuggerAgent->scriptDebugServer()); m_agents.append(std::make_unique<InspectorAgent>()); m_agents.append(std::move(runtimeAgent)); m_agents.append(std::move(consoleAgent)); m_agents.append(std::move(debuggerAgent)); }
void InspectorDebuggerAgent::removeBreakpoint(ErrorString*, const String& breakpointId) { RefPtr<InspectorObject> breakpointsCookie = m_state->getObject(DebuggerAgentState::javaScriptBreakpoints); breakpointsCookie->remove(breakpointId); m_state->setObject(DebuggerAgentState::javaScriptBreakpoints, breakpointsCookie); BreakpointIdToDebugServerBreakpointIdsMap::iterator debugServerBreakpointIdsIterator = m_breakpointIdToDebugServerBreakpointIds.find(breakpointId); if (debugServerBreakpointIdsIterator == m_breakpointIdToDebugServerBreakpointIds.end()) return; for (size_t i = 0; i < debugServerBreakpointIdsIterator->value.size(); ++i) scriptDebugServer().removeBreakpoint(debugServerBreakpointIdsIterator->value[i]); m_breakpointIdToDebugServerBreakpointIds.remove(debugServerBreakpointIdsIterator); }
void InspectorDebuggerAgent::evaluateOnCallFrame(ErrorString& errorString, const String& callFrameId, const String& expression, const String* const objectGroup, const bool* const includeCommandLineAPI, const bool* const doNotPauseOnExceptionsAndMuteConsole, const bool* const returnByValue, const bool* generatePreview, const bool* saveResult, RefPtr<Inspector::Protocol::Runtime::RemoteObject>& result, Inspector::Protocol::OptOutput<bool>* wasThrown, Inspector::Protocol::OptOutput<int>* savedResultIndex) { InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(callFrameId); if (injectedScript.hasNoValue()) { errorString = ASCIILiteral("Inspected frame has gone"); return; } JSC::Debugger::PauseOnExceptionsState previousPauseOnExceptionsState = scriptDebugServer().pauseOnExceptionsState(); if (doNotPauseOnExceptionsAndMuteConsole ? *doNotPauseOnExceptionsAndMuteConsole : false) { if (previousPauseOnExceptionsState != JSC::Debugger::DontPauseOnExceptions) scriptDebugServer().setPauseOnExceptionsState(JSC::Debugger::DontPauseOnExceptions); muteConsole(); } injectedScript.evaluateOnCallFrame(errorString, m_currentCallStack, callFrameId, expression, objectGroup ? *objectGroup : "", includeCommandLineAPI ? *includeCommandLineAPI : false, returnByValue ? *returnByValue : false, generatePreview ? *generatePreview : false, saveResult ? *saveResult : false, &result, wasThrown, savedResultIndex); if (doNotPauseOnExceptionsAndMuteConsole ? *doNotPauseOnExceptionsAndMuteConsole : false) { unmuteConsole(); if (scriptDebugServer().pauseOnExceptionsState() != previousPauseOnExceptionsState) scriptDebugServer().setPauseOnExceptionsState(previousPauseOnExceptionsState); } }
void InspectorDebuggerAgent::evaluateOnCallFrame(ErrorString* errorString, const String& callFrameId, const String& expression, const String* const objectGroup, const bool* const includeCommandLineAPI, const bool* const doNotPauseOnExceptionsAndMuteConsole, const bool* const returnByValue, RefPtr<TypeBuilder::Runtime::RemoteObject>& result, TypeBuilder::OptOutput<bool>* wasThrown) { InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(callFrameId); if (injectedScript.hasNoValue()) { *errorString = "Inspected frame has gone"; return; } ScriptDebugServer::PauseOnExceptionsState previousPauseOnExceptionsState = scriptDebugServer().pauseOnExceptionsState(); if (doNotPauseOnExceptionsAndMuteConsole ? *doNotPauseOnExceptionsAndMuteConsole : false) { if (previousPauseOnExceptionsState != ScriptDebugServer::DontPauseOnExceptions) scriptDebugServer().setPauseOnExceptionsState(ScriptDebugServer::DontPauseOnExceptions); muteConsole(); } injectedScript.evaluateOnCallFrame(errorString, m_currentCallStack, callFrameId, expression, objectGroup ? *objectGroup : "", includeCommandLineAPI ? *includeCommandLineAPI : false, returnByValue ? *returnByValue : false, &result, wasThrown); if (doNotPauseOnExceptionsAndMuteConsole ? *doNotPauseOnExceptionsAndMuteConsole : false) { unmuteConsole(); if (scriptDebugServer().pauseOnExceptionsState() != previousPauseOnExceptionsState) scriptDebugServer().setPauseOnExceptionsState(previousPauseOnExceptionsState); } }
WorkerInspectorController::WorkerInspectorController(WorkerGlobalScope& workerGlobalScope) : m_workerGlobalScope(workerGlobalScope) , m_instrumentingAgents(InstrumentingAgents::create(*this)) , m_injectedScriptManager(std::make_unique<WebInjectedScriptManager>(*this, WebInjectedScriptHost::create())) , m_executionStopwatch(Stopwatch::create()) , m_frontendRouter(FrontendRouter::create()) , m_backendDispatcher(BackendDispatcher::create(m_frontendRouter.copyRef())) { AgentContext baseContext = { *this, *m_injectedScriptManager, m_frontendRouter.get(), m_backendDispatcher.get() }; WebAgentContext webContext = { baseContext, m_instrumentingAgents.get() }; WorkerAgentContext workerContext = { webContext, workerGlobalScope, }; auto runtimeAgent = std::make_unique<WorkerRuntimeAgent>(workerContext); m_runtimeAgent = runtimeAgent.get(); m_instrumentingAgents->setWorkerRuntimeAgent(m_runtimeAgent); m_agents.append(WTF::move(runtimeAgent)); auto consoleAgent = std::make_unique<WorkerConsoleAgent>(workerContext); m_instrumentingAgents->setWebConsoleAgent(consoleAgent.get()); auto debuggerAgent = std::make_unique<WorkerDebuggerAgent>(workerContext); m_runtimeAgent->setScriptDebugServer(&debuggerAgent->scriptDebugServer()); m_agents.append(WTF::move(debuggerAgent)); m_agents.append(std::make_unique<InspectorTimelineAgent>(workerContext, nullptr, InspectorTimelineAgent::WorkerInspector)); m_agents.append(WTF::move(consoleAgent)); if (CommandLineAPIHost* commandLineAPIHost = m_injectedScriptManager->commandLineAPIHost()) { commandLineAPIHost->init(nullptr , nullptr , nullptr , nullptr , nullptr ); } }
WorkerInspectorController::WorkerInspectorController(WorkerGlobalScope& workerGlobalScope) : m_workerGlobalScope(workerGlobalScope) , m_instrumentingAgents(InstrumentingAgents::create(*this)) , m_injectedScriptManager(std::make_unique<WebInjectedScriptManager>(*this, WebInjectedScriptHost::create())) , m_runtimeAgent(nullptr) { auto runtimeAgent = std::make_unique<WorkerRuntimeAgent>(m_injectedScriptManager.get(), &workerGlobalScope); m_runtimeAgent = runtimeAgent.get(); m_instrumentingAgents->setWorkerRuntimeAgent(m_runtimeAgent); m_agents.append(std::move(runtimeAgent)); auto consoleAgent = std::make_unique<WorkerConsoleAgent>(m_injectedScriptManager.get()); m_instrumentingAgents->setWebConsoleAgent(consoleAgent.get()); auto debuggerAgent = std::make_unique<WorkerDebuggerAgent>(m_injectedScriptManager.get(), m_instrumentingAgents.get(), &workerGlobalScope); m_runtimeAgent->setScriptDebugServer(&debuggerAgent->scriptDebugServer()); m_agents.append(std::move(debuggerAgent)); auto profilerAgent = std::make_unique<WorkerProfilerAgent>(m_instrumentingAgents.get(), &workerGlobalScope); profilerAgent->setScriptDebugServer(&debuggerAgent->scriptDebugServer()); m_agents.append(std::move(profilerAgent)); m_agents.append(std::make_unique<InspectorTimelineAgent>(m_instrumentingAgents.get(), nullptr, InspectorTimelineAgent::WorkerInspector, nullptr)); m_agents.append(std::move(consoleAgent)); if (CommandLineAPIHost* commandLineAPIHost = m_injectedScriptManager->commandLineAPIHost()) { commandLineAPIHost->init(nullptr , nullptr , nullptr , nullptr #if ENABLE(SQL_DATABASE) , nullptr #endif ); } }
void InspectorDebuggerAgent::restartFrame(ErrorString* errorString, const String& callFrameId, RefPtr<Array<TypeBuilder::Debugger::CallFrame> >& newCallFrames, RefPtr<JSONObject>& result) { if (!isPaused() || m_currentCallStack.isNull()) { *errorString = "Attempt to access callframe when debugger is not on pause"; return; } InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(callFrameId); if (injectedScript.hasNoValue()) { *errorString = "Inspected frame has gone"; return; } injectedScript.restartFrame(errorString, m_currentCallStack, callFrameId, &result); scriptDebugServer().updateCallStack(&m_currentCallStack); newCallFrames = currentCallFrames(); }
void InspectorDebuggerAgent::compileScript(ErrorString* errorString, const String& expression, const String& sourceURL, TypeBuilder::OptOutput<ScriptId>* scriptId, TypeBuilder::OptOutput<String>* syntaxErrorMessage) { InjectedScript injectedScript = injectedScriptForEval(errorString, 0); if (injectedScript.hasNoValue()) { *errorString = "Inspected frame has gone"; return; } String scriptIdValue; String exceptionMessage; scriptDebugServer().compileScript(injectedScript.scriptState(), expression, sourceURL, &scriptIdValue, &exceptionMessage); if (!scriptIdValue && !exceptionMessage) { *errorString = "Script compilation failed"; return; } *syntaxErrorMessage = exceptionMessage; *scriptId = scriptIdValue; }
void InspectorDebuggerAgent::didPause(ScriptState* scriptState, const ScriptValue& callFrames, const ScriptValue& exception, const Vector<String>& hitBreakpoints) { ASSERT(scriptState && !m_pausedScriptState); m_pausedScriptState = scriptState; m_currentCallStack = callFrames; m_skipStepInCount = numberOfStepsBeforeStepOut; if (!exception.hasNoValue()) { InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(scriptState); if (!injectedScript.hasNoValue()) { m_breakReason = InspectorFrontend::Debugger::Reason::Exception; m_breakAuxData = injectedScript.wrapObject(exception, "backtrace")->openAccessors(); // m_breakAuxData might be null after this. } } RefPtr<Array<String> > hitBreakpointIds = Array<String>::create(); for (Vector<String>::const_iterator i = hitBreakpoints.begin(); i != hitBreakpoints.end(); ++i) { DebugServerBreakpointToBreakpointIdAndSourceMap::iterator breakpointIterator = m_serverBreakpoints.find(*i); if (breakpointIterator != m_serverBreakpoints.end()) { const String& localId = breakpointIterator->value.first; hitBreakpointIds->addItem(localId); BreakpointSource source = breakpointIterator->value.second; if (m_breakReason == InspectorFrontend::Debugger::Reason::Other && source == DebugCommandBreakpointSource) m_breakReason = InspectorFrontend::Debugger::Reason::DebugCommand; } } m_frontend->paused(currentCallFrames(), m_breakReason, m_breakAuxData, hitBreakpointIds); m_javaScriptPauseScheduled = false; if (!m_continueToLocationBreakpointId.isEmpty()) { scriptDebugServer().removeBreakpoint(m_continueToLocationBreakpointId); m_continueToLocationBreakpointId = ""; } if (m_listener) m_listener->didPause(); }
JSGlobalObjectInspectorController::JSGlobalObjectInspectorController(JSGlobalObject& globalObject) : m_globalObject(globalObject) , m_injectedScriptManager(std::make_unique<InjectedScriptManager>(*this, InjectedScriptHost::create())) , m_executionStopwatch(Stopwatch::create()) , m_frontendRouter(FrontendRouter::create()) , m_backendDispatcher(BackendDispatcher::create(m_frontendRouter.copyRef())) { AgentContext baseContext = { *this, *m_injectedScriptManager, m_frontendRouter.get(), m_backendDispatcher.get() }; JSAgentContext context = { baseContext, globalObject }; auto inspectorAgent = std::make_unique<InspectorAgent>(context); auto runtimeAgent = std::make_unique<JSGlobalObjectRuntimeAgent>(context); auto consoleAgent = std::make_unique<JSGlobalObjectConsoleAgent>(context); auto debuggerAgent = std::make_unique<JSGlobalObjectDebuggerAgent>(context, consoleAgent.get()); auto heapAgent = std::make_unique<InspectorHeapAgent>(context); m_inspectorAgent = inspectorAgent.get(); m_debuggerAgent = debuggerAgent.get(); m_heapAgent = heapAgent.get(); m_consoleAgent = consoleAgent.get(); m_consoleClient = std::make_unique<JSGlobalObjectConsoleClient>(m_consoleAgent); runtimeAgent->setScriptDebugServer(&debuggerAgent->scriptDebugServer()); m_agents.append(WTF::move(inspectorAgent)); m_agents.append(WTF::move(runtimeAgent)); m_agents.append(WTF::move(consoleAgent)); m_agents.append(WTF::move(debuggerAgent)); m_agents.append(WTF::move(heapAgent)); m_executionStopwatch->start(); }
void InspectorDebuggerAgent::didPause(ScriptState* scriptState, const ScriptValue& callFrames, const ScriptValue& exception) { ASSERT(scriptState && !m_pausedScriptState); m_pausedScriptState = scriptState; m_currentCallStack = callFrames; if (!exception.hasNoValue()) { InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(scriptState); if (!injectedScript.hasNoValue()) { m_breakReason = "exception"; m_breakAuxData = injectedScript.wrapObject(exception, "backtrace"); } } m_frontend->paused(currentCallFrames(), m_breakReason, m_breakAuxData); m_javaScriptPauseScheduled = false; if (!m_continueToLocationBreakpointId.isEmpty()) { scriptDebugServer().removeBreakpoint(m_continueToLocationBreakpointId); m_continueToLocationBreakpointId = ""; } }
void InspectorDebuggerAgent::didPause(ScriptState* scriptState, const ScriptValue& callFrames, const ScriptValue& exception) { ASSERT(scriptState && !m_pausedScriptState); m_pausedScriptState = scriptState; m_currentCallStack = callFrames; if (!m_breakProgramDetails) m_breakProgramDetails = InspectorObject::create(); m_breakProgramDetails->setValue("callFrames", currentCallFrames()); if (!exception.hasNoValue()) { InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(scriptState); if (!injectedScript.hasNoValue()) m_breakProgramDetails->setValue("exception", injectedScript.wrapObject(exception, "backtrace")); } m_frontend->paused(m_breakProgramDetails); m_javaScriptPauseScheduled = false; if (!m_continueToLocationBreakpointId.isEmpty()) { scriptDebugServer().removeBreakpoint(m_continueToLocationBreakpointId); m_continueToLocationBreakpointId = ""; } }