aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2022-07-11 20:17:11 +0200
committerGitHub <noreply@github.com>2022-07-11 20:17:11 +0200
commitb6e90de0aa7b53fdd5da1cb6924c4d039a8f2c56 (patch)
tree890aca90feb1f16c186083d53abedab598053a45
parent545383208e100e68bc74680b14d2081cf2f0a715 (diff)
parentcdcc3490720ef84d301c256605bcf34846bd1c1b (diff)
Merge pull request #6608 from bburdette/ignore-try
--ignore-try flag for debugger mode
-rw-r--r--src/libcmd/command.cc2
-rw-r--r--src/libcmd/command.hh1
-rw-r--r--src/libexpr/eval.cc12
-rw-r--r--src/libexpr/eval.hh7
-rw-r--r--src/libexpr/primops.cc17
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);
}