void JavaScriptDebugServer::pauseIfNeeded(Page* page) { if (m_paused) return; if (!page || !hasListenersInterestedInPage(page)) return; bool pauseNow = m_pauseOnNextStatement; pauseNow |= (m_pauseOnCallFrame == m_currentCallFrame); pauseNow |= (m_currentCallFrame->line() > 0 && hasBreakpoint(m_currentCallFrame->sourceIdentifier(), m_currentCallFrame->line())); if (!pauseNow) return; m_pauseOnCallFrame = 0; m_pauseOnNextStatement = false; m_paused = true; dispatchFunctionToListeners(&JavaScriptDebugListener::didPause, page); setJavaScriptPaused(page->group(), true); TimerBase::fireTimersInNestedEventLoop(); EventLoop loop; m_doneProcessingDebuggerEvents = false; while (!m_doneProcessingDebuggerEvents && !loop.ended()) loop.cycle(); setJavaScriptPaused(page->group(), false); m_paused = false; }
void ScriptDebugServer::pauseIfNeeded(JSGlobalObject* dynamicGlobalObject) { if (m_paused) return; if (!getListenersForGlobalObject(dynamicGlobalObject)) return; bool pauseNow = m_pauseOnNextStatement; pauseNow |= (m_pauseOnCallFrame == m_currentCallFrame); pauseNow |= hasBreakpoint(m_currentCallFrame->sourceID(), m_currentCallFrame->position()); m_lastExecutedLine = m_currentCallFrame->position().m_line.zeroBasedInt(); if (!pauseNow) return; m_pauseOnCallFrame = 0; m_pauseOnNextStatement = false; m_paused = true; dispatchFunctionToListeners(&ScriptDebugServer::dispatchDidPause, dynamicGlobalObject); didPause(dynamicGlobalObject); TimerBase::fireTimersInNestedEventLoop(); m_runningNestedMessageLoop = true; m_doneProcessingDebuggerEvents = false; runEventLoopWhilePaused(); m_runningNestedMessageLoop = false; didContinue(dynamicGlobalObject); dispatchFunctionToListeners(&ScriptDebugServer::dispatchDidContinue, dynamicGlobalObject); m_paused = false; }
void ScriptDebugServer::pauseIfNeeded(JSGlobalObject* dynamicGlobalObject) { if (m_paused) return; if (!getListenersForGlobalObject(dynamicGlobalObject)) return; bool pauseNow = m_pauseOnNextStatement; pauseNow |= (m_pauseOnCallFrame == m_currentCallFrame); pauseNow |= hasBreakpoint(m_currentCallFrame->sourceID(), m_currentCallFrame->position()); if (!pauseNow) return; m_pauseOnCallFrame = 0; m_pauseOnNextStatement = false; m_paused = true; dispatchFunctionToListeners(&ScriptDebugServer::dispatchDidPause, dynamicGlobalObject); didPause(dynamicGlobalObject); TimerBase::fireTimersInNestedEventLoop(); EventLoop loop; m_doneProcessingDebuggerEvents = false; while (!m_doneProcessingDebuggerEvents && !loop.ended()) loop.cycle(); didContinue(dynamicGlobalObject); dispatchFunctionToListeners(&ScriptDebugServer::dispatchDidContinue, dynamicGlobalObject); m_paused = false; }
void DebugManager::rewind() { int count = 0; bool breakPointActivated = false; while (historyPos > 0) { ++count; const TraceEntry& entry = instantiationHistory[--historyPos]; if (hasBreakpoint(entry.context) && count > 1) { breakPointActivated = true; break; } } if (count > 0) { for (int i = 0; i < this->eventHandlers.size(); ++i) eventHandlers[i]->rewind(count); if (breakPointActivated && count > 1) { next(); } } }
void Debugger::pauseIfNeeded(CallFrame* callFrame) { if (m_isPaused) return; if (m_suppressAllPauses) return; JSGlobalObject* vmEntryGlobalObject = callFrame->vmEntryGlobalObject(); if (!needPauseHandling(vmEntryGlobalObject)) return; Breakpoint breakpoint; bool didHitBreakpoint = false; bool pauseNow = m_pauseOnNextStatement; pauseNow |= (m_pauseOnCallFrame == m_currentCallFrame); DebuggerPausedScope debuggerPausedScope(*this); intptr_t sourceID = DebuggerCallFrame::sourceIDForCallFrame(m_currentCallFrame); TextPosition position = DebuggerCallFrame::positionForCallFrame(m_currentCallFrame); pauseNow |= didHitBreakpoint = hasBreakpoint(sourceID, position, &breakpoint); m_lastExecutedLine = position.m_line.zeroBasedInt(); if (!pauseNow) return; // Make sure we are not going to pause again on breakpoint actions by // reseting the pause state before executing any breakpoint actions. TemporaryPausedState pausedState(*this); m_pauseOnCallFrame = 0; m_pauseOnNextStatement = false; if (didHitBreakpoint) { handleBreakpointHit(vmEntryGlobalObject, breakpoint); // Note that the actions can potentially stop the debugger, so we need to check that // we still have a current call frame when we get back. if (breakpoint.autoContinue || !m_currentCallFrame) return; m_pausingBreakpointID = breakpoint.id; } { PauseReasonDeclaration reason(*this, didHitBreakpoint ? PausedForBreakpoint : m_reasonForPause); handlePause(vmEntryGlobalObject, m_reasonForPause); RELEASE_ASSERT(!callFrame->hadException()); } m_pausingBreakpointID = noBreakpointID; if (!m_pauseOnNextStatement && !m_pauseOnCallFrame) { setSteppingMode(SteppingModeDisabled); m_currentCallFrame = nullptr; } }
NaviError GdbSystem::processBreakpointMessage(const std::string& msg) { // If the received message is a breakpoint message, it // is necessary to find out where the breakpoint exception // occurred. // TODO: Not all require this cpu->sendAck(); CPUADDRESS address = 0; NaviError getProgramCounterError = getInstructionPointerFromStopMessage( msg, cpu->getInstructionPointerIndex(), address); if (getProgramCounterError) { msglog->log( LOG_VERBOSE, "Error: Couldn't read the value of the instruction pointer (Code %d)", getProgramCounterError); return getProgramCounterError; } synchronizeThreadState(); unsigned int threadId = threadFromBreakpointMessage(msg); NaviError eipResult = getInstructionPointer(threadId, address); address = cpu->correctBreakpointAddress(address); if (hasBreakpoint(address, BPX_simple) || hasBreakpoint(address, BPX_echo) || hasBreakpoint(address, BPX_stepping)) { handleBreakpointHit(address); } else if (cpu->getDebuggerOptions().canHalt) { // Some other reason caused the process to stop // If the target CPU can halt arbitrarily, let's hope // that the halt was caused by the user. } else { // None of our breakpoints and the target CPU can not // halt arbitrarily => Handle the issue farther up in the chain. handleBreakpointHit(address); } return NaviErrors::SUCCESS; }
void ScriptDebugServer::pauseIfNeeded(CallFrame* callFrame) { if (m_paused) return; JSGlobalObject* dynamicGlobalObject = callFrame->dynamicGlobalObject(); if (!getListenersForGlobalObject(dynamicGlobalObject)) return; ScriptBreakpoint breakpoint; bool didHitBreakpoint = false; bool pauseNow = m_pauseOnNextStatement; pauseNow |= (m_pauseOnCallFrame == m_currentCallFrame); intptr_t sourceId = DebuggerCallFrame::sourceIdForCallFrame(m_currentCallFrame); TextPosition position = DebuggerCallFrame::positionForCallFrame(m_currentCallFrame); pauseNow |= didHitBreakpoint = hasBreakpoint(sourceId, position, &breakpoint); m_lastExecutedLine = position.m_line.zeroBasedInt(); if (!pauseNow) return; DebuggerCallFrameScope debuggerCallFrameScope(*this); if (didHitBreakpoint) { evaluateBreakpointActions(breakpoint); if (breakpoint.autoContinue) return; } m_pauseOnCallFrame = 0; m_pauseOnNextStatement = false; m_paused = true; dispatchFunctionToListeners(&ScriptDebugServer::dispatchDidPause, dynamicGlobalObject); didPause(dynamicGlobalObject); TimerBase::fireTimersInNestedEventLoop(); m_runningNestedMessageLoop = true; m_doneProcessingDebuggerEvents = false; runEventLoopWhilePaused(); m_runningNestedMessageLoop = false; didContinue(dynamicGlobalObject); dispatchFunctionToListeners(&ScriptDebugServer::dispatchDidContinue, dynamicGlobalObject); m_paused = false; }
void DebugManager::forward() { std::vector<TraceEntry> entryVec; while (historyPos < instantiationHistory.size()) { const TraceEntry& entry = instantiationHistory[historyPos++]; entryVec.push_back(entry); if (hasBreakpoint(entry.context)) { break; } } if (!entryVec.empty()) { for (int i = 0; i < this->eventHandlers.size(); ++i) eventHandlers[i]->forward(entryVec); } }