aboutsummaryrefslogtreecommitdiff
path: root/src/libexpr/eval.cc
diff options
context:
space:
mode:
authorThéophane Hufschmitt <7226587+thufschmitt@users.noreply.github.com>2024-03-05 06:58:29 +0100
committereldritch horrors <pennae@lix.systems>2024-03-31 17:28:25 +0000
commit6c29016a0972f20cb0c91a4d9c8020f09baf6293 (patch)
tree5acbafb203e465d030d6d41bf447ce9d552eb360 /src/libexpr/eval.cc
parent45623f077fdd53eb227bfee94f061835e86742ff (diff)
Merge pull request #9920 from 9999years/forbid-nested-debuggers
Forbid nested debuggers (cherry picked from commit e164b39ee90fd655dbb7f479fdd4fbe38cc883bd) Change-Id: Iff62f40fd251116516a63e2d3f9fb5b21480b16d
Diffstat (limited to 'src/libexpr/eval.cc')
-rw-r--r--src/libexpr/eval.cc19
1 files changed, 17 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: