in src/debugger/RDebugger.cpp [254:335]
SEXP RDebugger::doStep(SEXP expr, SEXP env, SEXP srcref, bool alwaysStop, RContext *callContext) {
bool suspend = false;
if (rDebugger.isEnabled()) {
auto position = getPosition(srcref);
VirtualFileInfo* virtualFile = position.first;
switch (currentCommand) {
case CONTINUE:
break;
case PAUSE:
suspend = true;
break;
case STEP_INTO:
suspend = true;
break;
case STEP_INTO_MY_CODE:
suspend = virtualFile != nullptr && !virtualFile->isGenerated;
break;
case ABORT:
setCommand(CONTINUE);
R_interrupts_pending = 1;
R_CheckUserInterrupt();
return R_NilValue;
case STEP_OVER:
case STEP_OUT: {
if (callContext == nullptr) callContext = getCurrentCallContext();
SEXP callEnv = callContext == bottomContext ? bottomContextRealEnv : getEnvironment(callContext);
auto it = contextsToStop.find(callEnv);
if (it != contextsToStop.end() && it->second >= getEvalDepth(callContext)) {
suspend = true;
}
break;
}
case RUN_TO_POSITION:
suspend = virtualFile != nullptr && virtualFile->extPtr == runToPositionTarget.first && position.second == runToPositionTarget.second;
break;
}
int line = position.second;
Breakpoint* breakpoint;
if (virtualFile == nullptr || virtualFile->breakpointsByLine.size() <= line) {
breakpoint = nullptr;
} else {
auto const& vector = virtualFile->breakpointsByLine[line];
breakpoint = vector.empty() ? nullptr : vector[0];
}
if (!breakpointsMuted && breakpoint != nullptr && breakpoint->enabled && (breakpoint->master == nullptr || breakpoint->masterWasHit) &&
Rf_getAttrib(srcref, RI->noBreakpointFlag) == R_NilValue) {
CPP_BEGIN
if (checkCondition(breakpoint->condition, env)) {
if (!breakpoint->slaveLeaveEnabled) breakpoint->masterWasHit = false;
for (Breakpoint *slave : breakpoint->slaves) {
slave->masterWasHit = true;
}
if (breakpoint->hitMessage) {
printHitMessage(virtualFile, line);
}
if (breakpoint->printStack) {
printStack(buildStack(getContextDump(expr)));
}
evaluateAndLog(breakpoint->evaluateAndLog, env);
if (breakpoint->suspend) {
suspend = true;
}
if (breakpoint->removeAfterHit) {
AsyncEvent e;
e.set_debugremovebreakpointrequest(breakpoint->id);
rDebugger.removeBreakpointById(breakpoint->id);
rpiService->sendAsyncEvent(e);
}
}
CPP_END_VOID
}
if (alwaysStop) suspend = true;
}
if (suspend) {
CPP_BEGIN
sendDebugPrompt(expr);
CPP_END_VOID
}
return Rf_eval(expr, env);
}