diff options
Diffstat (limited to 'src/libexpr')
-rw-r--r-- | src/libexpr/eval.cc | 19 | ||||
-rw-r--r-- | src/libexpr/eval.hh | 2 |
2 files changed, 19 insertions, 2 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index bef0effb6..b24f10c24 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -778,10 +778,24 @@ std::unique_ptr<ValMap> mapStaticEnvBindings(const SymbolTable & st, const Stati return vm; } +/** + * Sets `inDebugger` to true on construction and false on destruction. + */ +class DebuggerGuard { + bool & inDebugger; +public: + DebuggerGuard(bool & inDebugger) : inDebugger(inDebugger) { + inDebugger = true; + } + ~DebuggerGuard() { + inDebugger = false; + } +}; + void EvalState::runDebugRepl(const Error * error, const Env & env, const Expr & expr) { - // double check we've got the debugRepl function pointer. - if (!debugRepl) + // Make sure we have a debugger to run and we're not already in a debugger. + if (!debugRepl || inDebugger) return; auto dts = @@ -808,6 +822,7 @@ void EvalState::runDebugRepl(const Error * error, const Env & env, const Expr & auto se = getStaticEnv(expr); if (se) { auto vm = mapStaticEnvBindings(symbols, *se.get(), env); + DebuggerGuard _guard(inDebugger); auto exitStatus = (debugRepl)(ref<EvalState>(shared_from_this()), *vm); switch (exitStatus) { case ReplExitStatus::QuitAll: diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh index d2d8140e9..2291d618c 100644 --- a/src/libexpr/eval.hh +++ b/src/libexpr/eval.hh @@ -152,6 +152,7 @@ struct DebugTrace { bool isError; }; + class EvalState : public std::enable_shared_from_this<EvalState> { public: @@ -210,6 +211,7 @@ public: */ ReplExitStatus (* debugRepl)(ref<EvalState> es, const ValMap & extraEnv); bool debugStop; + bool inDebugger = false; int trylevel; std::list<DebugTrace> debugTraces; std::map<const Expr*, const std::shared_ptr<const StaticEnv>> exprEnvs; |