// Handle a continue cmd, or setup stepping. void DebuggerProxy::processFlowControl(CmdInterrupt &cmd) { TRACE(2, "DebuggerProxy::processFlowControl\n"); switch (m_flow->getType()) { case DebuggerCommand::KindOfContinue: if (!m_flow->decCount()) { m_flow.reset(); } break; case DebuggerCommand::KindOfStep: { // allows the breakpoint to be hit again when returns // from function call BreakPointInfoPtr bp = getBreakPointAtCmd(cmd); if (bp) { bp->setBreakable(getRealStackDepth()); } break; } case DebuggerCommand::KindOfOut: case DebuggerCommand::KindOfNext: m_flow->setStackDepth(getStackDepth()); m_flow->setVMDepth(g_vmContext->m_nesting); m_flow->setFileLine(cmd.getFileLine()); break; default: assert(false); break; } }
// Allow breaks for previously disabled breakpoints that do not match the site // of cmd. (Call this when processing an interrupt since this probably means // that execution has moved away from the previous interrupt site.) void DebuggerProxy::setBreakableForBreakpointsNotMatching(CmdInterrupt& cmd) { TRACE(2, "DebuggerProxy::setBreakableForBreakpointsNotMatching\n"); auto stackDepth = getRealStackDepth(); for (unsigned int i = 0; i < m_breakpoints.size(); ++i) { BreakPointInfoPtr bp = m_breakpoints[i]; if (bp != nullptr && bp->m_state != BreakPointInfo::Disabled && !bp->match(*this, cmd.getInterruptType(), *cmd.getSite())) { bp->setBreakable(stackDepth); } } }
void CmdStep::onSetup(DebuggerProxy *proxy, CmdInterrupt &interrupt) { assert(!m_complete); // Complete cmds should not be asked to do work. CmdFlowControl::onSetup(proxy, interrupt); // Allows a breakpoint on this same line to be hit again when control returns // from function call. BreakPointInfoPtr bp = proxy->getBreakPointAtCmd(interrupt); if (bp) { bp->setBreakable(proxy->getRealStackDepth()); } installLocationFilterForLine(interrupt.getSite()); m_needsVMInterrupt = true; }