From 6c29016a0972f20cb0c91a4d9c8020f09baf6293 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9ophane=20Hufschmitt?= <7226587+thufschmitt@users.noreply.github.com> Date: Tue, 5 Mar 2024 06:58:29 +0100 Subject: Merge pull request #9920 from 9999years/forbid-nested-debuggers Forbid nested debuggers (cherry picked from commit e164b39ee90fd655dbb7f479fdd4fbe38cc883bd) Change-Id: Iff62f40fd251116516a63e2d3f9fb5b21480b16d --- src/libexpr/eval.cc | 19 +++++++++++++++++-- src/libexpr/eval.hh | 2 ++ 2 files changed, 19 insertions(+), 2 deletions(-) (limited to 'src/libexpr') 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 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(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 { public: @@ -210,6 +211,7 @@ public: */ ReplExitStatus (* debugRepl)(ref es, const ValMap & extraEnv); bool debugStop; + bool inDebugger = false; int trylevel; std::list debugTraces; std::map> exprEnvs; -- cgit v1.2.3