From e5eebda19475ab4f25346128e5428c27e526c7ce Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Thu, 23 Dec 2021 13:36:39 -0700 Subject: [PATCH] DebugTrace --- src/libcmd/command.cc | 2 +- src/libcmd/command.hh | 4 +--- src/libcmd/repl.cc | 11 +++++------ src/libexpr/eval.cc | 22 +++++++++++++++------- src/libexpr/eval.hh | 8 +++++++- 5 files changed, 29 insertions(+), 18 deletions(-) diff --git a/src/libcmd/command.cc b/src/libcmd/command.cc index 0ada5fa3c..6c0f84c4b 100644 --- a/src/libcmd/command.cc +++ b/src/libcmd/command.cc @@ -84,7 +84,7 @@ ref EvalCommand::getEvalState() if (expr.staticenv) { auto vm = mapStaticEnvBindings(*expr.staticenv.get(), env); - runRepl(evalState, ref(&error), *vm); + runRepl(evalState, &error, *vm); } }; } diff --git a/src/libcmd/command.hh b/src/libcmd/command.hh index e27ee2e9e..e2c72256e 100644 --- a/src/libcmd/command.hh +++ b/src/libcmd/command.hh @@ -314,8 +314,6 @@ void printClosureDiff( void runRepl( ref evalState, - std::optional> debugError, + const Error *debugError, const std::map & extraEnv); - - } diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index 3289aea3e..6859e5c07 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -50,7 +50,7 @@ struct NixRepl ref state; Bindings * autoArgs; - std::optional> debugError; + const Error *debugError; Strings loadedFiles; @@ -470,13 +470,12 @@ bool NixRepl::processLine(string line) } else if (arg == "error") { - if (this->debugError.has_value()) { - // TODO user --show-trace setting? - showErrorInfo(std::cout, (*debugError)->info(), true); + if (this->debugError) { + showErrorInfo(std::cout, debugError->info(), true); } else { - notice("error information not available"); + notice("error information not available"); } } } @@ -893,7 +892,7 @@ std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int m void runRepl( ref evalState, - std::optional> debugError, + const Error *debugError, const std::map & extraEnv) { auto repl = std::make_unique(evalState); diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index d7deb550e..b8d060276 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -40,7 +40,7 @@ std::function deb class DebugTraceStacker { public: - DebugTraceStacker(EvalState &evalState, Trace t) + DebugTraceStacker(EvalState &evalState, DebugTrace t) :evalState(evalState), trace(t) { evalState.debugTraces.push_front(t); @@ -50,7 +50,7 @@ class DebugTraceStacker { evalState.debugTraces.pop_front(); } EvalState &evalState; - Trace trace; + DebugTrace trace; }; static char * dupString(const char * s) @@ -911,12 +911,14 @@ LocalNoInline(void addErrorTrace(Error & e, const Pos & pos, const char * s, con } LocalNoInline(std::unique_ptr - makeDebugTraceStacker(EvalState &state, std::optional pos, const char * s, const string & s2)) + makeDebugTraceStacker(EvalState &state, Expr &expr, std::optional pos, const char * s, const string & s2)) { return std::unique_ptr( new DebugTraceStacker( state, - Trace {.pos = pos, + DebugTrace + {.pos = pos, + .expr = expr, .hint = hintfmt(s, s2) })); } @@ -1143,6 +1145,7 @@ void EvalState::cacheFile( debuggerHook ? makeDebugTraceStacker( *this, + *e, (e->getPos() ? std::optional(ErrPos(*e->getPos())) : std::nullopt), "while evaluating the file '%1%':", resolvedPath) : std::unique_ptr(); @@ -1375,6 +1378,7 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v) debuggerHook ? makeDebugTraceStacker( state, + *this, *pos2, "while evaluating the attribute '%1%'", showAttrPath(state, env, attrPath)) @@ -1524,7 +1528,7 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value & try { std::unique_ptr dts = debuggerHook ? - makeDebugTraceStacker(*this, lambda.pos, + makeDebugTraceStacker(*this, *lambda.body, lambda.pos, "while evaluating %s", (lambda.name.set() ? "'" + (string) lambda.name + "'" @@ -1925,10 +1929,14 @@ void EvalState::forceValueDeep(Value & v) if (v.type() == nAttrs) { for (auto & i : *v.attrs) try { + std::unique_ptr dts = debuggerHook ? - makeDebugTraceStacker(*this, *i.pos, - "while evaluating the attribute '%1%'", i.name) + // if the value is a thunk, we're evaling. otherwise no trace necessary. + (i.value->isThunk() ? + makeDebugTraceStacker(*this, *v.thunk.expr, *i.pos, + "while evaluating the attribute '%1%'", i.name) + : std::unique_ptr()) : std::unique_ptr(); recurse(*i.value); diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh index c3717b3c2..c7a19e100 100644 --- a/src/libexpr/eval.hh +++ b/src/libexpr/eval.hh @@ -74,6 +74,12 @@ struct RegexCache; std::shared_ptr makeRegexCache(); +struct DebugTrace { + std::optional pos; + Expr &expr; + hintformat hint; +}; + class EvalState { @@ -109,7 +115,7 @@ public: RootValue vCallFlake = nullptr; RootValue vImportedDrvToDerivation = nullptr; - std::list debugTraces; + std::list debugTraces; private: SrcToStore srcToStore;