From b4a59a5eec5bdb94ee2bbc8365f024d5787abd60 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Wed, 22 Dec 2021 15:38:49 -0700 Subject: [PATCH] DebugStackTracker class in one place --- src/libcmd/command.cc | 2 ++ src/libcmd/repl.cc | 1 + src/libexpr/eval.cc | 65 ++++++++++++++++++++++++++++++++++++++++-- src/libexpr/eval.hh | 2 ++ src/libexpr/nixexpr.hh | 25 ++++++++++++++++ src/libutil/error.cc | 2 ++ src/libutil/logging.hh | 1 + 7 files changed, 96 insertions(+), 2 deletions(-) diff --git a/src/libcmd/command.cc b/src/libcmd/command.cc index b37959a2e..0ada5fa3c 100644 --- a/src/libcmd/command.cc +++ b/src/libcmd/command.cc @@ -75,6 +75,8 @@ ref EvalCommand::getEvalState() printStaticEnvBindings(expr); + std::cout << evalState->vCallFlake << std::endl; + std::cout << "expr: " << std::endl; expr.show(std::cout); std::cout << std::endl; diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index 0eea2389b..2a925df64 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -451,6 +451,7 @@ 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); } else diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 8737930b5..00d2c1643 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -17,6 +17,7 @@ #include #include #include +#include #include @@ -854,13 +855,20 @@ LocalNoInlineNoReturn(void throwAssertionError(const Pos & pos, const char * s, LocalNoInlineNoReturn(void throwUndefinedVarError(const Pos & pos, const char * s, const string & s1, Env & env, Expr *expr)) { + std::cout << "throwUndefinedVarError" << std::endl; + + std::cout << "loggerSettings.showTrace: " << loggerSettings.showTrace << std::endl; + auto error = UndefinedVarError({ .msg = hintfmt(s, s1), .errPos = pos }); - if (debuggerHook && expr) + if (debuggerHook && expr) { + + std::cout << "throwUndefinedVarError debuggerHook" << std::endl; debuggerHook(error, env, *expr); + } throw error; } @@ -888,6 +896,16 @@ LocalNoInline(void addErrorTrace(Error & e, const Pos & pos, const char * s, con e.addTrace(pos, s, s2); } +// LocalNoInline(void makeErrorTrace(Error & e, const char * s, const string & s2)) +// { +// Trace { .pos = e, .hint = hint } +// } + +// LocalNoInline(void makeErrorTrace(Error & e, const Pos & pos, const char * s, const string & s2)) +// { +// return Trace { .pos = e, .hint = hintfmt(s, s2); }; +// } + void mkString(Value & v, const char * s) { v.mkString(dupString(s)); @@ -934,7 +952,7 @@ inline Value * EvalState::lookupVar(Env * env, const ExprVar & var, bool noEval) return j->value; } if (!env->prevWith) { - throwUndefinedVarError(var.pos, "undefined variable '%1%'", var.name, *env, 0); + throwUndefinedVarError(var.pos, "undefined variable '%1%'", var.name, *env, (Expr*)&var); } for (size_t l = env->prevWith; l; --l, env = env->up) ; } @@ -1092,6 +1110,39 @@ void EvalState::resetFileCache() fileParseCache.clear(); } +class DebugTraceStacker { + public: + DebugTraceStacker(EvalState &evalState, Trace t) + :evalState(evalState), trace(t) + { + evalState.debugTraces.push_front(t); + } + ~DebugTraceStacker() { + // assert(evalState.debugTraces.front() == trace); + evalState.debugTraces.pop_front(); + } + + EvalState &evalState; + Trace trace; + +}; + +// class DebugTraceStacker { +// DebugTraceStacker(std::ref evalState, std::ref t) +// :evalState(evalState), trace(t) +// { +// evalState->debugTraces.push_front(t); +// } +// ~DebugTraceStacker() { +// assert(evalState->debugTraces.pop_front() == trace); +// } + +// std::ref evalState; +// std::ref trace; + +// }; + + void EvalState::cacheFile( const Path & path, @@ -1103,6 +1154,15 @@ void EvalState::cacheFile( fileParseCache[resolvedPath] = e; try { + std::unique_ptr dts = debuggerHook ? + std::unique_ptr(new DebugTraceStacker(*this, + Trace { .pos = (e->getPos() ? std::optional(ErrPos(*e->getPos())) : std::nullopt), + .hint = hintfmt("while evaluating the file '%1%':", resolvedPath) + } + )) : std::unique_ptr(); + + // Trace( .pos = (e->getPos() ? std::optional(ErrPos(*e->getPos())): + // std::nullopt), hintfmt("while evaluating the file '%1%':", resolvedPath)); // Enforce that 'flake.nix' is a direct attrset, not a // computation. if (mustBeTrivial && @@ -1472,6 +1532,7 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value & try { lambda.body->eval(*this, env2, vCur); } catch (Error & e) { + std::cout << "eval showErrorInfo showTrace: " << loggerSettings.showTrace.get() << std::endl; if (loggerSettings.showTrace.get()) { addErrorTrace(e, lambda.pos, "while evaluating %s", (lambda.name.set() diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh index 4b3e7d69a..c3717b3c2 100644 --- a/src/libexpr/eval.hh +++ b/src/libexpr/eval.hh @@ -109,6 +109,8 @@ public: RootValue vCallFlake = nullptr; RootValue vImportedDrvToDerivation = nullptr; + std::list debugTraces; + private: SrcToStore srcToStore; diff --git a/src/libexpr/nixexpr.hh b/src/libexpr/nixexpr.hh index 825933fa1..a9a5f5316 100644 --- a/src/libexpr/nixexpr.hh +++ b/src/libexpr/nixexpr.hh @@ -84,6 +84,7 @@ struct Expr virtual void setName(Symbol & name); std::shared_ptr staticenv; + virtual Pos* getPos() = 0; }; std::ostream & operator << (std::ostream & str, const Expr & e); @@ -100,6 +101,8 @@ struct ExprInt : Expr ExprInt(NixInt n) : n(n) { mkInt(v, n); }; COMMON_METHODS Value * maybeThunk(EvalState & state, Env & env); + + Pos* getPos() { return 0; } }; struct ExprFloat : Expr @@ -109,6 +112,8 @@ struct ExprFloat : Expr ExprFloat(NixFloat nf) : nf(nf) { mkFloat(v, nf); }; COMMON_METHODS Value * maybeThunk(EvalState & state, Env & env); + + Pos* getPos() { return 0; } }; struct ExprString : Expr @@ -118,6 +123,8 @@ struct ExprString : Expr ExprString(const Symbol & s) : s(s) { mkString(v, s); }; COMMON_METHODS Value * maybeThunk(EvalState & state, Env & env); + + Pos* getPos() { return 0; } }; /* Temporary class used during parsing of indented strings. */ @@ -125,6 +132,8 @@ struct ExprIndStr : Expr { string s; ExprIndStr(const string & s) : s(s) { }; + + Pos* getPos() { return 0; } }; struct ExprPath : Expr @@ -134,6 +143,7 @@ struct ExprPath : Expr ExprPath(const string & s) : s(s) { v.mkPath(this->s.c_str()); }; COMMON_METHODS Value * maybeThunk(EvalState & state, Env & env); + Pos* getPos() { return 0; } }; typedef uint32_t Level; @@ -161,6 +171,7 @@ struct ExprVar : Expr ExprVar(const Pos & pos, const Symbol & name) : pos(pos), name(name) { }; COMMON_METHODS Value * maybeThunk(EvalState & state, Env & env); + Pos* getPos() { return &pos; } }; struct ExprSelect : Expr @@ -171,6 +182,7 @@ struct ExprSelect : Expr ExprSelect(const Pos & pos, Expr * e, const AttrPath & attrPath, Expr * def) : pos(pos), e(e), def(def), attrPath(attrPath) { }; ExprSelect(const Pos & pos, Expr * e, const Symbol & name) : pos(pos), e(e), def(0) { attrPath.push_back(AttrName(name)); }; COMMON_METHODS + Pos* getPos() { return &pos; } }; struct ExprOpHasAttr : Expr @@ -179,6 +191,7 @@ struct ExprOpHasAttr : Expr AttrPath attrPath; ExprOpHasAttr(Expr * e, const AttrPath & attrPath) : e(e), attrPath(attrPath) { }; COMMON_METHODS + Pos* getPos() { return e->getPos(); } }; struct ExprAttrs : Expr @@ -207,6 +220,7 @@ struct ExprAttrs : Expr ExprAttrs(const Pos &pos) : recursive(false), pos(pos) { }; ExprAttrs() : recursive(false), pos(noPos) { }; COMMON_METHODS + Pos* getPos() { return &pos; } }; struct ExprList : Expr @@ -214,6 +228,7 @@ struct ExprList : Expr std::vector elems; ExprList() { }; COMMON_METHODS + Pos* getPos() { return 0; } }; struct Formal @@ -252,6 +267,7 @@ struct ExprLambda : Expr string showNamePos() const; inline bool hasFormals() const { return formals != nullptr; } COMMON_METHODS + Pos* getPos() { return &pos; } }; struct ExprCall : Expr @@ -263,6 +279,7 @@ struct ExprCall : Expr : fun(fun), args(args), pos(pos) { } COMMON_METHODS + Pos* getPos() { return &pos; } }; struct ExprLet : Expr @@ -271,6 +288,7 @@ struct ExprLet : Expr Expr * body; ExprLet(ExprAttrs * attrs, Expr * body) : attrs(attrs), body(body) { }; COMMON_METHODS + Pos* getPos() { return 0; } }; struct ExprWith : Expr @@ -280,6 +298,7 @@ struct ExprWith : Expr size_t prevWith; ExprWith(const Pos & pos, Expr * attrs, Expr * body) : pos(pos), attrs(attrs), body(body) { }; COMMON_METHODS + Pos* getPos() { return &pos; } }; struct ExprIf : Expr @@ -288,6 +307,7 @@ struct ExprIf : Expr Expr * cond, * then, * else_; ExprIf(const Pos & pos, Expr * cond, Expr * then, Expr * else_) : pos(pos), cond(cond), then(then), else_(else_) { }; COMMON_METHODS + Pos* getPos() { return &pos; } }; struct ExprAssert : Expr @@ -296,6 +316,7 @@ struct ExprAssert : Expr Expr * cond, * body; ExprAssert(const Pos & pos, Expr * cond, Expr * body) : pos(pos), cond(cond), body(body) { }; COMMON_METHODS + Pos* getPos() { return &pos; } }; struct ExprOpNot : Expr @@ -303,6 +324,7 @@ struct ExprOpNot : Expr Expr * e; ExprOpNot(Expr * e) : e(e) { }; COMMON_METHODS + Pos* getPos() { return 0; } }; #define MakeBinOp(name, s) \ @@ -321,6 +343,7 @@ struct ExprOpNot : Expr e1->bindVars(env); e2->bindVars(env); \ } \ void eval(EvalState & state, Env & env, Value & v); \ + Pos* getPos() { return &pos; } \ }; MakeBinOp(ExprOpEq, "==") @@ -339,6 +362,7 @@ struct ExprConcatStrings : Expr ExprConcatStrings(const Pos & pos, bool forceString, vector * es) : pos(pos), forceString(forceString), es(es) { }; COMMON_METHODS + Pos* getPos() { return &pos; } }; struct ExprPos : Expr @@ -346,6 +370,7 @@ struct ExprPos : Expr Pos pos; ExprPos(const Pos & pos) : pos(pos) { }; COMMON_METHODS + Pos* getPos() { return &pos; } }; diff --git a/src/libutil/error.cc b/src/libutil/error.cc index 203d79087..c2b9d2707 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -221,6 +221,8 @@ static std::string indent(std::string_view indentFirst, std::string_view indentR std::ostream & showErrorInfo(std::ostream & out, const ErrorInfo & einfo, bool showTrace) { + std::cout << "showErrorInfo showTrace: " << showTrace << std::endl; + std::string prefix; switch (einfo.level) { case Verbosity::lvlError: { diff --git a/src/libutil/logging.hh b/src/libutil/logging.hh index 96ad69790..f10a9af38 100644 --- a/src/libutil/logging.hh +++ b/src/libutil/logging.hh @@ -38,6 +38,7 @@ typedef uint64_t ActivityId; struct LoggerSettings : Config { Setting showTrace{ + // this, false, "show-trace", this, false, "show-trace", R"( Where Nix should print out a stack trace in case of Nix