diff options
author | Eelco Dolstra <edolstra@gmail.com> | 2022-07-11 20:17:11 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-07-11 20:17:11 +0200 |
commit | b6e90de0aa7b53fdd5da1cb6924c4d039a8f2c56 (patch) | |
tree | 890aca90feb1f16c186083d53abedab598053a45 | |
parent | 545383208e100e68bc74680b14d2081cf2f0a715 (diff) | |
parent | cdcc3490720ef84d301c256605bcf34846bd1c1b (diff) |
Merge pull request #6608 from bburdette/ignore-try
--ignore-try flag for debugger mode
-rw-r--r-- | src/libcmd/command.cc | 2 | ||||
-rw-r--r-- | src/libcmd/command.hh | 1 | ||||
-rw-r--r-- | src/libexpr/eval.cc | 12 | ||||
-rw-r--r-- | src/libexpr/eval.hh | 7 | ||||
-rw-r--r-- | src/libexpr/primops.cc | 17 |
5 files changed, 36 insertions, 3 deletions
diff --git a/src/libcmd/command.cc b/src/libcmd/command.cc index 7f8072d75..14bb27936 100644 --- a/src/libcmd/command.cc +++ b/src/libcmd/command.cc @@ -120,7 +120,7 @@ ref<EvalState> EvalCommand::getEvalState() ; if (startReplOnEvalErrors) { - evalState->debugRepl = &runRepl; + evalState->debugRepl = &runRepl; }; } return ref<EvalState>(evalState); diff --git a/src/libcmd/command.hh b/src/libcmd/command.hh index 3df6cd114..6bd38810b 100644 --- a/src/libcmd/command.hh +++ b/src/libcmd/command.hh @@ -58,6 +58,7 @@ struct CopyCommand : virtual StoreCommand struct EvalCommand : virtual StoreCommand, MixEvalArgs { bool startReplOnEvalErrors = false; + bool ignoreExceptionsDuringTry = false; EvalCommand(); diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 40462afdf..f485e2fed 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -464,9 +464,10 @@ EvalState::EvalState( , emptyBindings(0) , store(store) , buildStore(buildStore ? buildStore : store) - , debugRepl(0) + , debugRepl(nullptr) , debugStop(false) , debugQuit(false) + , trylevel(0) , regexCache(makeRegexCache()) #if HAVE_BOEHMGC , valueAllocCache(std::allocate_shared<void *>(traceable_allocator<void *>(), nullptr)) @@ -832,7 +833,14 @@ void EvalState::runDebugRepl(const Error * error, const Env & env, const Expr & : nullptr; if (error) - printError("%s\n\n" ANSI_BOLD "Starting REPL to allow you to inspect the current state of the evaluator.\n" ANSI_NORMAL, error->what()); + { + printError("%s\n\n", error->what()); + + if (trylevel > 0 && error->info().level != lvlInfo) + printError("This exception occurred in a 'tryEval' call. Use " ANSI_GREEN "--ignore-try" ANSI_NORMAL " to skip these.\n"); + + printError(ANSI_BOLD "Starting REPL to allow you to inspect the current state of the evaluator.\n" ANSI_NORMAL); + } auto se = getStaticEnv(expr); if (se) { diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh index 7db954bf4..f07f15d43 100644 --- a/src/libexpr/eval.hh +++ b/src/libexpr/eval.hh @@ -130,6 +130,7 @@ public: void (* debugRepl)(ref<EvalState> es, const ValMap & extraEnv); bool debugStop; bool debugQuit; + int trylevel; std::list<DebugTrace> debugTraces; std::map<const Expr*, const std::shared_ptr<const StaticEnv>> exprEnvs; const std::shared_ptr<const StaticEnv> getStaticEnv(const Expr & expr) const @@ -647,6 +648,12 @@ struct EvalSettings : Config Setting<bool> useEvalCache{this, true, "eval-cache", "Whether to use the flake evaluation cache."}; + Setting<bool> ignoreExceptionsDuringTry{this, false, "ignore-try", + R"( + If set to true, ignore exceptions inside 'tryEval' calls when evaluating nix expressions in + debug mode (using the --debugger flag). By default the debugger will pause on all exceptions. + )"}; + Setting<bool> traceVerbose{this, false, "trace-verbose", "Whether `builtins.traceVerbose` should trace its first argument when evaluated."}; }; diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index 5fda9af75..bc253d0a3 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -851,6 +851,18 @@ static RegisterPrimOp primop_floor({ static void prim_tryEval(EvalState & state, const PosIdx pos, Value * * args, Value & v) { auto attrs = state.buildBindings(2); + + /* increment state.trylevel, and decrement it when this function returns. */ + MaintainCount trylevel(state.trylevel); + + void (* savedDebugRepl)(ref<EvalState> es, const ValMap & extraEnv) = nullptr; + if (state.debugRepl && evalSettings.ignoreExceptionsDuringTry) + { + /* to prevent starting the repl from exceptions withing a tryEval, null it. */ + savedDebugRepl = state.debugRepl; + state.debugRepl = nullptr; + } + try { state.forceValue(*args[0], pos); attrs.insert(state.sValue, args[0]); @@ -859,6 +871,11 @@ static void prim_tryEval(EvalState & state, const PosIdx pos, Value * * args, Va attrs.alloc(state.sValue).mkBool(false); attrs.alloc("success").mkBool(false); } + + // restore the debugRepl pointer if we saved it earlier. + if (savedDebugRepl) + state.debugRepl = savedDebugRepl; + v.mkAttrs(attrs); } |