aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoreldritch horrors <pennae@lix.systems>2024-03-08 06:38:10 +0100
committereldritch horrors <pennae@lix.systems>2024-03-09 03:37:35 -0700
commit3e1be9c5304f87d84409a91c8c8a867ceaa21c3e (patch)
tree2d748e082a733ca02256cfa7219e0457c9a475c2
parent379681157172658825e4b647eec9477dd5d8f05d (diff)
Merge pull request #9917 from 9999years/enter-debugger-more-reliably
Enter debugger more reliably in `let` expressions and function calls (cherry picked from commit c4ed92fa6f836d3d8eb354a48c37a2f9eeecc3aa) Change-Id: I16d0cad7e898feecd2399723b92ba8df67222fb4
-rw-r--r--doc/manual/rl-next/enter-debugger-more-reliably-in-let-and-calls.md25
-rw-r--r--src/libexpr/eval.cc31
2 files changed, 53 insertions, 3 deletions
diff --git a/doc/manual/rl-next/enter-debugger-more-reliably-in-let-and-calls.md b/doc/manual/rl-next/enter-debugger-more-reliably-in-let-and-calls.md
new file mode 100644
index 000000000..c93225816
--- /dev/null
+++ b/doc/manual/rl-next/enter-debugger-more-reliably-in-let-and-calls.md
@@ -0,0 +1,25 @@
+---
+synopsis: The `--debugger` will start more reliably in `let` expressions and function calls
+prs: 9917
+issues: 6649
+---
+
+Previously, if you attempted to evaluate this file with the debugger:
+
+```nix
+let
+ a = builtins.trace "before inner break" (
+ builtins.break "hello"
+ );
+ b = builtins.trace "before outer break" (
+ builtins.break a
+ );
+in
+ b
+```
+
+Nix would correctly enter the debugger at `builtins.break a`, but if you asked
+it to `:continue`, it would skip over the `builtins.break "hello"` expression
+entirely.
+
+Now, Nix will correctly enter the debugger at both breakpoints.
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index d86177ec7..98bf086ec 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -852,20 +852,20 @@ void EvalState::addErrorTrace(Error & e, const PosIdx pos, const char * s, const
e.addTrace(positions[pos], hintfmt(s, s2), frame);
}
+template<typename... Args>
static std::unique_ptr<DebugTraceStacker> makeDebugTraceStacker(
EvalState & state,
Expr & expr,
Env & env,
std::shared_ptr<Pos> && pos,
- const char * s,
- const std::string & s2)
+ const Args & ... formatArgs)
{
return std::make_unique<DebugTraceStacker>(state,
DebugTrace {
.pos = std::move(pos),
.expr = expr,
.env = env,
- .hint = hintfmt(s, s2),
+ .hint = hintfmt(formatArgs...),
.isError = false
});
}
@@ -1341,6 +1341,19 @@ void ExprLet::eval(EvalState & state, Env & env, Value & v)
for (auto & i : attrs->attrs)
env2.values[displ++] = i.second.e->maybeThunk(state, i.second.inherited ? env : env2);
+ auto dts = state.debugRepl
+ ? makeDebugTraceStacker(
+ state,
+ *this,
+ env2,
+ getPos()
+ ? std::make_shared<Pos>(state.positions[getPos()])
+ : nullptr,
+ "while evaluating a '%1%' expression",
+ "let"
+ )
+ : nullptr;
+
body->eval(state, env2, v);
}
@@ -1737,6 +1750,18 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value &
void ExprCall::eval(EvalState & state, Env & env, Value & v)
{
+ auto dts = state.debugRepl
+ ? makeDebugTraceStacker(
+ state,
+ *this,
+ env,
+ getPos()
+ ? std::make_shared<Pos>(state.positions[getPos()])
+ : nullptr,
+ "while calling a function"
+ )
+ : nullptr;
+
Value vFun;
fun->eval(state, env, vFun);