DebugTrace

This commit is contained in:
Ben Burdette 2021-12-23 13:36:39 -07:00
parent deb1fd66e8
commit e5eebda194
5 changed files with 29 additions and 18 deletions

View file

@ -84,7 +84,7 @@ ref<EvalState> EvalCommand::getEvalState()
if (expr.staticenv) if (expr.staticenv)
{ {
auto vm = mapStaticEnvBindings(*expr.staticenv.get(), env); auto vm = mapStaticEnvBindings(*expr.staticenv.get(), env);
runRepl(evalState, ref<const Error>(&error), *vm); runRepl(evalState, &error, *vm);
} }
}; };
} }

View file

@ -314,8 +314,6 @@ void printClosureDiff(
void runRepl( void runRepl(
ref<EvalState> evalState, ref<EvalState> evalState,
std::optional<ref<const Error>> debugError, const Error *debugError,
const std::map<std::string, Value *> & extraEnv); const std::map<std::string, Value *> & extraEnv);
} }

View file

@ -50,7 +50,7 @@ struct NixRepl
ref<EvalState> state; ref<EvalState> state;
Bindings * autoArgs; Bindings * autoArgs;
std::optional<ref<const Error>> debugError; const Error *debugError;
Strings loadedFiles; Strings loadedFiles;
@ -470,13 +470,12 @@ bool NixRepl::processLine(string line)
} }
else if (arg == "error") { else if (arg == "error") {
if (this->debugError.has_value()) { if (this->debugError) {
// TODO user --show-trace setting? showErrorInfo(std::cout, debugError->info(), true);
showErrorInfo(std::cout, (*debugError)->info(), true);
} }
else 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( void runRepl(
ref<EvalState> evalState, ref<EvalState> evalState,
std::optional<ref<const Error>> debugError, const Error *debugError,
const std::map<std::string, Value *> & extraEnv) const std::map<std::string, Value *> & extraEnv)
{ {
auto repl = std::make_unique<NixRepl>(evalState); auto repl = std::make_unique<NixRepl>(evalState);

View file

@ -40,7 +40,7 @@ std::function<void(const Error & error, const Env & env, const Expr & expr)> deb
class DebugTraceStacker { class DebugTraceStacker {
public: public:
DebugTraceStacker(EvalState &evalState, Trace t) DebugTraceStacker(EvalState &evalState, DebugTrace t)
:evalState(evalState), trace(t) :evalState(evalState), trace(t)
{ {
evalState.debugTraces.push_front(t); evalState.debugTraces.push_front(t);
@ -50,7 +50,7 @@ class DebugTraceStacker {
evalState.debugTraces.pop_front(); evalState.debugTraces.pop_front();
} }
EvalState &evalState; EvalState &evalState;
Trace trace; DebugTrace trace;
}; };
static char * dupString(const char * s) 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<DebugTraceStacker> LocalNoInline(std::unique_ptr<DebugTraceStacker>
makeDebugTraceStacker(EvalState &state, std::optional<ErrPos> pos, const char * s, const string & s2)) makeDebugTraceStacker(EvalState &state, Expr &expr, std::optional<ErrPos> pos, const char * s, const string & s2))
{ {
return std::unique_ptr<DebugTraceStacker>( return std::unique_ptr<DebugTraceStacker>(
new DebugTraceStacker( new DebugTraceStacker(
state, state,
Trace {.pos = pos, DebugTrace
{.pos = pos,
.expr = expr,
.hint = hintfmt(s, s2) .hint = hintfmt(s, s2)
})); }));
} }
@ -1143,6 +1145,7 @@ void EvalState::cacheFile(
debuggerHook ? debuggerHook ?
makeDebugTraceStacker( makeDebugTraceStacker(
*this, *this,
*e,
(e->getPos() ? std::optional(ErrPos(*e->getPos())) : std::nullopt), (e->getPos() ? std::optional(ErrPos(*e->getPos())) : std::nullopt),
"while evaluating the file '%1%':", resolvedPath) "while evaluating the file '%1%':", resolvedPath)
: std::unique_ptr<DebugTraceStacker>(); : std::unique_ptr<DebugTraceStacker>();
@ -1375,6 +1378,7 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v)
debuggerHook ? debuggerHook ?
makeDebugTraceStacker( makeDebugTraceStacker(
state, state,
*this,
*pos2, *pos2,
"while evaluating the attribute '%1%'", "while evaluating the attribute '%1%'",
showAttrPath(state, env, attrPath)) showAttrPath(state, env, attrPath))
@ -1524,7 +1528,7 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value &
try { try {
std::unique_ptr<DebugTraceStacker> dts = std::unique_ptr<DebugTraceStacker> dts =
debuggerHook ? debuggerHook ?
makeDebugTraceStacker(*this, lambda.pos, makeDebugTraceStacker(*this, *lambda.body, lambda.pos,
"while evaluating %s", "while evaluating %s",
(lambda.name.set() (lambda.name.set()
? "'" + (string) lambda.name + "'" ? "'" + (string) lambda.name + "'"
@ -1925,10 +1929,14 @@ void EvalState::forceValueDeep(Value & v)
if (v.type() == nAttrs) { if (v.type() == nAttrs) {
for (auto & i : *v.attrs) for (auto & i : *v.attrs)
try { try {
std::unique_ptr<DebugTraceStacker> dts = std::unique_ptr<DebugTraceStacker> dts =
debuggerHook ? debuggerHook ?
makeDebugTraceStacker(*this, *i.pos, // if the value is a thunk, we're evaling. otherwise no trace necessary.
"while evaluating the attribute '%1%'", i.name) (i.value->isThunk() ?
makeDebugTraceStacker(*this, *v.thunk.expr, *i.pos,
"while evaluating the attribute '%1%'", i.name)
: std::unique_ptr<DebugTraceStacker>())
: std::unique_ptr<DebugTraceStacker>(); : std::unique_ptr<DebugTraceStacker>();
recurse(*i.value); recurse(*i.value);

View file

@ -74,6 +74,12 @@ struct RegexCache;
std::shared_ptr<RegexCache> makeRegexCache(); std::shared_ptr<RegexCache> makeRegexCache();
struct DebugTrace {
std::optional<ErrPos> pos;
Expr &expr;
hintformat hint;
};
class EvalState class EvalState
{ {
@ -109,7 +115,7 @@ public:
RootValue vCallFlake = nullptr; RootValue vCallFlake = nullptr;
RootValue vImportedDrvToDerivation = nullptr; RootValue vImportedDrvToDerivation = nullptr;
std::list<Trace> debugTraces; std::list<DebugTrace> debugTraces;
private: private:
SrcToStore srcToStore; SrcToStore srcToStore;