bool Debugger::hasBreakpoint(SourceID sourceID, const TextPosition& position, Breakpoint *hitBreakpoint) { if (!m_breakpointsActivated) return false; SourceIDToBreakpointsMap::const_iterator it = m_sourceIDToBreakpoints.find(sourceID); if (it == m_sourceIDToBreakpoints.end()) return false; unsigned line = position.m_line.zeroBasedInt(); unsigned column = position.m_column.zeroBasedInt(); LineToBreakpointsMap::const_iterator breaksIt = it->value.find(line); if (breaksIt == it->value.end()) return false; bool hit = false; const BreakpointsInLine& breakpoints = breaksIt->value; unsigned breakpointsCount = breakpoints.size(); unsigned i; for (i = 0; i < breakpointsCount; i++) { unsigned breakLine = breakpoints[i].line; unsigned breakColumn = breakpoints[i].column; // Since frontend truncates the indent, the first statement in a line must match the breakpoint (line,0). ASSERT(this == m_currentCallFrame->codeBlock()->globalObject()->debugger()); if ((line != m_lastExecutedLine && line == breakLine && !breakColumn) || (line == breakLine && column == breakColumn)) { hit = true; break; } } if (!hit) return false; if (hitBreakpoint) *hitBreakpoint = breakpoints[i]; if (breakpoints[i].condition.isEmpty()) return true; // We cannot stop in the debugger while executing condition code, // so make it looks like the debugger is already paused. TemporaryPausedState pausedState(*this); JSValue exception; DebuggerCallFrame* debuggerCallFrame = currentDebuggerCallFrame(); JSValue result = debuggerCallFrame->evaluate(breakpoints[i].condition, exception); // We can lose the debugger while executing JavaScript. if (!m_currentCallFrame) return false; if (exception) { // An erroneous condition counts as "false". handleExceptionInBreakpointCondition(m_currentCallFrame, exception); return false; } return result.toBoolean(m_currentCallFrame); }
void ScriptDebugServer::dispatchDidPause(ScriptDebugListener* listener) { ASSERT(isPaused()); DebuggerCallFrame* debuggerCallFrame = currentDebuggerCallFrame(); JSGlobalObject* globalObject = debuggerCallFrame->scope()->globalObject(); JSC::ExecState* state = globalObject->globalExec(); RefPtr<JavaScriptCallFrame> javaScriptCallFrame = JavaScriptCallFrame::create(debuggerCallFrame); JSValue jsCallFrame = toJS(state, globalObject, javaScriptCallFrame.get()); listener->didPause(state, Deprecated::ScriptValue(state->vm(), jsCallFrame), Deprecated::ScriptValue()); }
void ScriptDebugServer::willExecuteProgram(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineNumber, int columnNumber) { if (!m_paused) { createCallFrame(debuggerCallFrame, sourceID, lineNumber, columnNumber); pauseIfNeeded(debuggerCallFrame.dynamicGlobalObject()); } }
void JavaScriptDebugServer::willExecuteProgram(const DebuggerCallFrame& debuggerCallFrame, int sourceID, int lineNumber) { if (m_paused) return; m_currentCallFrame = JavaScriptCallFrame::create(debuggerCallFrame, m_currentCallFrame, sourceID, lineNumber); pauseIfNeeded(toPage(debuggerCallFrame.dynamicGlobalObject())); }
void DebuggerShell::exception(const DebuggerCallFrame& callFrame, intptr_t sourceID, int lineNumber, int column, bool hasHandler) { ExecState *execState = callFrame.dynamicGlobalObject()->globalExec(); WTF::CString exceptString = callFrame.exception().toString(execState)->getString(execState).ascii(); if (tracing_ || !hasHandler) { WTF::CString f = WTF::String::format("Exception (%shandled) at "WHEREAMI_FMT": %s", hasHandler ? "" : "un", WHEREAMI_DATA, exceptString.data()).ascii(); std::string& url = source_map_[sourceID].url; if (hasHandler) { dumpToTTY(f); } else { dumpToTTYPopup(f); pause_ASAP_ = true; } } maybeBlockExecution(callFrame); }
void ScriptDebugServer::dispatchDidPause(ScriptDebugListener* listener) { ASSERT(m_paused); DebuggerCallFrame* debuggerCallFrame = currentDebuggerCallFrame(); JSGlobalObject* globalObject = debuggerCallFrame->scope()->globalObject(); JSC::ExecState* state = globalObject->globalExec(); RefPtr<JavaScriptCallFrame> javaScriptCallFrame = JavaScriptCallFrame::create(debuggerCallFrame); JSValue jsCallFrame; { if (globalObject->inherits(JSDOMGlobalObject::info())) { JSDOMGlobalObject* domGlobalObject = jsCast<JSDOMGlobalObject*>(globalObject); JSLockHolder lock(state); jsCallFrame = toJS(state, domGlobalObject, javaScriptCallFrame.get()); } else jsCallFrame = jsUndefined(); } listener->didPause(state, ScriptValue(state->vm(), jsCallFrame), ScriptValue()); }
void ScriptDebugServer::updateCallFrameAndPauseIfNeeded(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineNumber) { ASSERT(m_currentCallFrame); if (!m_currentCallFrame) return; TextPosition textPosition(OrdinalNumber::fromOneBasedInt(lineNumber), OrdinalNumber::first()); m_currentCallFrame->update(debuggerCallFrame, sourceID, textPosition); pauseIfNeeded(debuggerCallFrame.dynamicGlobalObject()); }
void ScriptDebugServer::updateCallFrameAndPauseIfNeeded(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineNumber) { ASSERT(m_currentCallFrame); if (!m_currentCallFrame) return; TextPosition0 textPosition(WTF::OneBasedNumber::fromOneBasedInt(lineNumber).convertToZeroBased(), WTF::ZeroBasedNumber::base()); m_currentCallFrame->update(debuggerCallFrame, sourceID, textPosition); pauseIfNeeded(debuggerCallFrame.dynamicGlobalObject()); }
void JavaScriptDebugServer::atStatement(const DebuggerCallFrame& debuggerCallFrame, int sourceID, int lineNumber) { if (m_paused) return; ASSERT(m_currentCallFrame); if (!m_currentCallFrame) return; m_currentCallFrame->update(debuggerCallFrame, sourceID, lineNumber); pauseIfNeeded(toPage(debuggerCallFrame.dynamicGlobalObject())); }
bool ScriptDebugServer::evaluateBreakpointAction(const ScriptBreakpointAction& breakpointAction) const { DebuggerCallFrame* debuggerCallFrame = currentDebuggerCallFrame(); switch (breakpointAction.type) { case ScriptBreakpointActionTypeLog: { DOMWindow& window = asJSDOMWindow(debuggerCallFrame->dynamicGlobalObject())->impl(); if (PageConsole* console = window.pageConsole()) console->addMessage(JSMessageSource, LogMessageLevel, breakpointAction.data); break; } case ScriptBreakpointActionTypeEvaluate: { JSValue exception; debuggerCallFrame->evaluate(breakpointAction.data, exception); if (exception) reportException(debuggerCallFrame->exec(), exception); break; } case ScriptBreakpointActionTypeSound: systemBeep(); break; } return true; }
void JavaScriptDebugServer::didExecuteProgram(const DebuggerCallFrame& debuggerCallFrame, int sourceID, int lineNumber) { if (m_paused) return; ASSERT(m_currentCallFrame); if (!m_currentCallFrame) return; m_currentCallFrame->update(debuggerCallFrame, sourceID, lineNumber); pauseIfNeeded(toPage(debuggerCallFrame.dynamicGlobalObject())); // Treat stepping over the end of a program like stepping out. if (m_currentCallFrame == m_pauseOnCallFrame) m_pauseOnCallFrame = m_currentCallFrame->caller(); m_currentCallFrame = m_currentCallFrame->caller(); }
bool ScriptDebugServer::evaluateBreakpointAction(const ScriptBreakpointAction& breakpointAction) { DebuggerCallFrame* debuggerCallFrame = currentDebuggerCallFrame(); switch (breakpointAction.type) { case ScriptBreakpointActionTypeLog: { dispatchBreakpointActionLog(debuggerCallFrame->exec(), breakpointAction.data); break; } case ScriptBreakpointActionTypeEvaluate: { JSValue exception; debuggerCallFrame->evaluate(breakpointAction.data, exception); if (exception) reportException(debuggerCallFrame->exec(), exception); break; } case ScriptBreakpointActionTypeSound: dispatchBreakpointActionSound(debuggerCallFrame->exec()); break; case ScriptBreakpointActionTypeProbe: { JSValue exception; JSValue result = debuggerCallFrame->evaluate(breakpointAction.data, exception); if (exception) reportException(debuggerCallFrame->exec(), exception); JSC::ExecState* state = debuggerCallFrame->scope()->globalObject()->globalExec(); Deprecated::ScriptValue wrappedResult = Deprecated::ScriptValue(state->vm(), exception ? exception : result); dispatchDidSampleProbe(state, breakpointAction.identifier, wrappedResult); break; } default: ASSERT_NOT_REACHED(); } return true; }
void ScriptDebugServer::createCallFrameAndPauseIfNeeded(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineNumber) { TextPosition textPosition(OrdinalNumber::fromOneBasedInt(lineNumber), OrdinalNumber::first()); m_currentCallFrame = JavaScriptCallFrame::create(debuggerCallFrame, m_currentCallFrame, sourceID, textPosition); pauseIfNeeded(debuggerCallFrame.dynamicGlobalObject()); }
void ScriptDebugServer::createCallFrameAndPauseIfNeeded(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineNumber) { TextPosition0 textPosition(WTF::OneBasedNumber::fromOneBasedInt(lineNumber).convertToZeroBased(), WTF::ZeroBasedNumber::base()); m_currentCallFrame = JavaScriptCallFrame::create(debuggerCallFrame, m_currentCallFrame, sourceID, textPosition); pauseIfNeeded(debuggerCallFrame.dynamicGlobalObject()); }