in src/debugger/RDebugger.cpp [412:451]
std::vector<RDebugger::ContextDump> RDebugger::getContextDumpErr() {
ScopedAssign<Rboolean> with(R_interrupts_suspended, (Rboolean)TRUE);
SEXP rho = R_GlobalEnv;
RContext* ctx = getGlobalContext();
while (ctx != nullptr) {
if (isCallContext(ctx)) {
rho = getEnvironment(ctx);
break;
}
ctx = getNextContext(ctx);
}
ShieldSEXP calls = RI->sysCalls.invokeUnsafeInEnv(rho);
ShieldSEXP frames = RI->sysFrames.invokeUnsafeInEnv(rho);
std::vector<ContextDump> dump;
for (int i = frames.length() - 1; i >= 0; --i) {
SEXP func;
try {
func = safeEval(Rf_lang2(RI->sysFunction, toSEXP(i + 1)), rho);
} catch (RExceptionBase const&) {
func = R_NilValue;
}
ContextDump current = {
calls[i],
func,
Rf_getAttrib(calls[i], RI->srcrefAttr),
frames[i]
};
dump.push_back(current);
if (ctx == nullptr || ctx == bottomContext) {
dump.back().environment = bottomContextRealEnv;
dump.back().call = nullptr;
break;
}
do {
ctx = getNextContext(ctx);
} while (ctx != nullptr && !isCallContext(ctx));
}
std::reverse(dump.begin(), dump.end());
return dump;
}