aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Burdette <bburdette@gmail.com>2021-12-22 15:38:49 -0700
committerBen Burdette <bburdette@gmail.com>2021-12-22 15:38:49 -0700
commitb4a59a5eec5bdb94ee2bbc8365f024d5787abd60 (patch)
tree8b9f2ebb64f06cd2dca5efdeb58c6870a41dbd50
parentf317019edda7afac8590e68d4d979b03a2cdbf62 (diff)
DebugStackTracker class in one place
-rw-r--r--src/libcmd/command.cc2
-rw-r--r--src/libcmd/repl.cc1
-rw-r--r--src/libexpr/eval.cc65
-rw-r--r--src/libexpr/eval.hh2
-rw-r--r--src/libexpr/nixexpr.hh25
-rw-r--r--src/libutil/error.cc2
-rw-r--r--src/libutil/logging.hh1
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<EvalState> 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 <sys/resource.h>
#include <iostream>
#include <fstream>
+#include <functional>
#include <sys/resource.h>
@@ -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> evalState, std::ref<Trace> t)
+// :evalState(evalState), trace(t)
+// {
+// evalState->debugTraces.push_front(t);
+// }
+// ~DebugTraceStacker() {
+// assert(evalState->debugTraces.pop_front() == trace);
+// }
+
+// std::ref<EvalState> evalState;
+// std::ref<Trace> trace;
+
+// };
+
+
void EvalState::cacheFile(
const Path & path,
@@ -1103,6 +1154,15 @@ void EvalState::cacheFile(
fileParseCache[resolvedPath] = e;
try {
+ std::unique_ptr<DebugTraceStacker> dts = debuggerHook ?
+ std::unique_ptr<DebugTraceStacker>(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<DebugTraceStacker>();
+
+ // 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<Trace> 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<const StaticEnv> 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<Expr *> 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<Expr *> * 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<bool> showTrace{
+ // this, false, "show-trace",
this, false, "show-trace",
R"(
Where Nix should print out a stack trace in case of Nix