aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/manual/rl-next/debugger-on-trace.md9
-rw-r--r--src/libexpr/eval-settings.hh10
-rw-r--r--src/libexpr/primops.cc10
3 files changed, 29 insertions, 0 deletions
diff --git a/doc/manual/rl-next/debugger-on-trace.md b/doc/manual/rl-next/debugger-on-trace.md
new file mode 100644
index 000000000..721928550
--- /dev/null
+++ b/doc/manual/rl-next/debugger-on-trace.md
@@ -0,0 +1,9 @@
+---
+synopsis: Enter the `--debugger` when `builtins.trace` is called if `debugger-on-trace` is set
+prs: 9914
+---
+
+If the `debugger-on-trace` option is set and `--debugger` is given,
+`builtins.trace` calls will behave similarly to `builtins.break` and will enter
+the debug REPL. This is useful for determining where warnings are being emitted
+from.
diff --git a/src/libexpr/eval-settings.hh b/src/libexpr/eval-settings.hh
index 7a92b9728..c78213255 100644
--- a/src/libexpr/eval-settings.hh
+++ b/src/libexpr/eval-settings.hh
@@ -114,6 +114,16 @@ struct EvalSettings : Config
Setting<unsigned int> maxCallDepth{this, 10000, "max-call-depth",
"The maximum function call depth to allow before erroring."};
+
+ Setting<bool> builtinsTraceDebugger{this, false, "debugger-on-trace",
+ R"(
+ If set to true and the `--debugger` flag is given,
+ [`builtins.trace`](@docroot@/language/builtins.md#builtins-trace) will
+ enter the debugger like
+ [`builtins.break`](@docroot@/language/builtins.md#builtins-break).
+
+ This is useful for debugging warnings in third-party Nix code.
+ )"};
};
extern EvalSettings evalSettings;
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index 30933e191..b5b28efcd 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -980,6 +980,10 @@ static void prim_trace(EvalState & state, const PosIdx pos, Value * * args, Valu
printError("trace: %1%", args[0]->string.s);
else
printError("trace: %1%", ValuePrinter(state, *args[0]));
+ if (evalSettings.builtinsTraceDebugger && state.debugRepl && !state.debugTraces.empty()) {
+ const DebugTrace & last = state.debugTraces.front();
+ state.runDebugRepl(nullptr, last.env, last.expr);
+ }
state.forceValue(*args[1], pos);
v = *args[1];
}
@@ -991,6 +995,12 @@ static RegisterPrimOp primop_trace({
Evaluate *e1* and print its abstract syntax representation on
standard error. Then return *e2*. This function is useful for
debugging.
+
+ If the
+ [`debugger-on-trace`](@docroot@/command-ref/conf-file.md#conf-debugger-on-trace)
+ option is set to `true` and the `--debugger` flag is given, the
+ interactive debugger will be started when `trace` is called (like
+ [`break`](@docroot@/language/builtins.md#builtins-break)).
)",
.fun = prim_trace,
});