forked from lix-project/lix
DebugStackTracker class in one place
This commit is contained in:
parent
f317019edd
commit
b4a59a5eec
|
@ -75,6 +75,8 @@ ref<EvalState> EvalCommand::getEvalState()
|
||||||
|
|
||||||
printStaticEnvBindings(expr);
|
printStaticEnvBindings(expr);
|
||||||
|
|
||||||
|
std::cout << evalState->vCallFlake << std::endl;
|
||||||
|
|
||||||
std::cout << "expr: " << std::endl;
|
std::cout << "expr: " << std::endl;
|
||||||
expr.show(std::cout);
|
expr.show(std::cout);
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
|
@ -451,6 +451,7 @@ bool NixRepl::processLine(string line)
|
||||||
}
|
}
|
||||||
else if (arg == "error") {
|
else if (arg == "error") {
|
||||||
if (this->debugError.has_value()) {
|
if (this->debugError.has_value()) {
|
||||||
|
// TODO user --show-trace setting?
|
||||||
showErrorInfo(std::cout, (*debugError)->info(), true);
|
showErrorInfo(std::cout, (*debugError)->info(), true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
#include <sys/resource.h>
|
#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))
|
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({
|
auto error = UndefinedVarError({
|
||||||
.msg = hintfmt(s, s1),
|
.msg = hintfmt(s, s1),
|
||||||
.errPos = pos
|
.errPos = pos
|
||||||
});
|
});
|
||||||
|
|
||||||
if (debuggerHook && expr)
|
if (debuggerHook && expr) {
|
||||||
|
|
||||||
|
std::cout << "throwUndefinedVarError debuggerHook" << std::endl;
|
||||||
debuggerHook(error, env, *expr);
|
debuggerHook(error, env, *expr);
|
||||||
|
}
|
||||||
|
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
@ -888,6 +896,16 @@ LocalNoInline(void addErrorTrace(Error & e, const Pos & pos, const char * s, con
|
||||||
e.addTrace(pos, s, s2);
|
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)
|
void mkString(Value & v, const char * s)
|
||||||
{
|
{
|
||||||
v.mkString(dupString(s));
|
v.mkString(dupString(s));
|
||||||
|
@ -934,7 +952,7 @@ inline Value * EvalState::lookupVar(Env * env, const ExprVar & var, bool noEval)
|
||||||
return j->value;
|
return j->value;
|
||||||
}
|
}
|
||||||
if (!env->prevWith) {
|
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) ;
|
for (size_t l = env->prevWith; l; --l, env = env->up) ;
|
||||||
}
|
}
|
||||||
|
@ -1092,6 +1110,39 @@ void EvalState::resetFileCache()
|
||||||
fileParseCache.clear();
|
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(
|
void EvalState::cacheFile(
|
||||||
const Path & path,
|
const Path & path,
|
||||||
|
@ -1103,6 +1154,15 @@ void EvalState::cacheFile(
|
||||||
fileParseCache[resolvedPath] = e;
|
fileParseCache[resolvedPath] = e;
|
||||||
|
|
||||||
try {
|
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
|
// Enforce that 'flake.nix' is a direct attrset, not a
|
||||||
// computation.
|
// computation.
|
||||||
if (mustBeTrivial &&
|
if (mustBeTrivial &&
|
||||||
|
@ -1472,6 +1532,7 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value &
|
||||||
try {
|
try {
|
||||||
lambda.body->eval(*this, env2, vCur);
|
lambda.body->eval(*this, env2, vCur);
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
|
std::cout << "eval showErrorInfo showTrace: " << loggerSettings.showTrace.get() << std::endl;
|
||||||
if (loggerSettings.showTrace.get()) {
|
if (loggerSettings.showTrace.get()) {
|
||||||
addErrorTrace(e, lambda.pos, "while evaluating %s",
|
addErrorTrace(e, lambda.pos, "while evaluating %s",
|
||||||
(lambda.name.set()
|
(lambda.name.set()
|
||||||
|
|
|
@ -109,6 +109,8 @@ public:
|
||||||
RootValue vCallFlake = nullptr;
|
RootValue vCallFlake = nullptr;
|
||||||
RootValue vImportedDrvToDerivation = nullptr;
|
RootValue vImportedDrvToDerivation = nullptr;
|
||||||
|
|
||||||
|
std::list<Trace> debugTraces;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SrcToStore srcToStore;
|
SrcToStore srcToStore;
|
||||||
|
|
||||||
|
|
|
@ -84,6 +84,7 @@ struct Expr
|
||||||
virtual void setName(Symbol & name);
|
virtual void setName(Symbol & name);
|
||||||
|
|
||||||
std::shared_ptr<const StaticEnv> staticenv;
|
std::shared_ptr<const StaticEnv> staticenv;
|
||||||
|
virtual Pos* getPos() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::ostream & operator << (std::ostream & str, const Expr & e);
|
std::ostream & operator << (std::ostream & str, const Expr & e);
|
||||||
|
@ -100,6 +101,8 @@ struct ExprInt : Expr
|
||||||
ExprInt(NixInt n) : n(n) { mkInt(v, n); };
|
ExprInt(NixInt n) : n(n) { mkInt(v, n); };
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
Value * maybeThunk(EvalState & state, Env & env);
|
Value * maybeThunk(EvalState & state, Env & env);
|
||||||
|
|
||||||
|
Pos* getPos() { return 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ExprFloat : Expr
|
struct ExprFloat : Expr
|
||||||
|
@ -109,6 +112,8 @@ struct ExprFloat : Expr
|
||||||
ExprFloat(NixFloat nf) : nf(nf) { mkFloat(v, nf); };
|
ExprFloat(NixFloat nf) : nf(nf) { mkFloat(v, nf); };
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
Value * maybeThunk(EvalState & state, Env & env);
|
Value * maybeThunk(EvalState & state, Env & env);
|
||||||
|
|
||||||
|
Pos* getPos() { return 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ExprString : Expr
|
struct ExprString : Expr
|
||||||
|
@ -118,6 +123,8 @@ struct ExprString : Expr
|
||||||
ExprString(const Symbol & s) : s(s) { mkString(v, s); };
|
ExprString(const Symbol & s) : s(s) { mkString(v, s); };
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
Value * maybeThunk(EvalState & state, Env & env);
|
Value * maybeThunk(EvalState & state, Env & env);
|
||||||
|
|
||||||
|
Pos* getPos() { return 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Temporary class used during parsing of indented strings. */
|
/* Temporary class used during parsing of indented strings. */
|
||||||
|
@ -125,6 +132,8 @@ struct ExprIndStr : Expr
|
||||||
{
|
{
|
||||||
string s;
|
string s;
|
||||||
ExprIndStr(const string & s) : s(s) { };
|
ExprIndStr(const string & s) : s(s) { };
|
||||||
|
|
||||||
|
Pos* getPos() { return 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ExprPath : Expr
|
struct ExprPath : Expr
|
||||||
|
@ -134,6 +143,7 @@ struct ExprPath : Expr
|
||||||
ExprPath(const string & s) : s(s) { v.mkPath(this->s.c_str()); };
|
ExprPath(const string & s) : s(s) { v.mkPath(this->s.c_str()); };
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
Value * maybeThunk(EvalState & state, Env & env);
|
Value * maybeThunk(EvalState & state, Env & env);
|
||||||
|
Pos* getPos() { return 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef uint32_t Level;
|
typedef uint32_t Level;
|
||||||
|
@ -161,6 +171,7 @@ struct ExprVar : Expr
|
||||||
ExprVar(const Pos & pos, const Symbol & name) : pos(pos), name(name) { };
|
ExprVar(const Pos & pos, const Symbol & name) : pos(pos), name(name) { };
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
Value * maybeThunk(EvalState & state, Env & env);
|
Value * maybeThunk(EvalState & state, Env & env);
|
||||||
|
Pos* getPos() { return &pos; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ExprSelect : Expr
|
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 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)); };
|
ExprSelect(const Pos & pos, Expr * e, const Symbol & name) : pos(pos), e(e), def(0) { attrPath.push_back(AttrName(name)); };
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
|
Pos* getPos() { return &pos; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ExprOpHasAttr : Expr
|
struct ExprOpHasAttr : Expr
|
||||||
|
@ -179,6 +191,7 @@ struct ExprOpHasAttr : Expr
|
||||||
AttrPath attrPath;
|
AttrPath attrPath;
|
||||||
ExprOpHasAttr(Expr * e, const AttrPath & attrPath) : e(e), attrPath(attrPath) { };
|
ExprOpHasAttr(Expr * e, const AttrPath & attrPath) : e(e), attrPath(attrPath) { };
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
|
Pos* getPos() { return e->getPos(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ExprAttrs : Expr
|
struct ExprAttrs : Expr
|
||||||
|
@ -207,6 +220,7 @@ struct ExprAttrs : Expr
|
||||||
ExprAttrs(const Pos &pos) : recursive(false), pos(pos) { };
|
ExprAttrs(const Pos &pos) : recursive(false), pos(pos) { };
|
||||||
ExprAttrs() : recursive(false), pos(noPos) { };
|
ExprAttrs() : recursive(false), pos(noPos) { };
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
|
Pos* getPos() { return &pos; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ExprList : Expr
|
struct ExprList : Expr
|
||||||
|
@ -214,6 +228,7 @@ struct ExprList : Expr
|
||||||
std::vector<Expr *> elems;
|
std::vector<Expr *> elems;
|
||||||
ExprList() { };
|
ExprList() { };
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
|
Pos* getPos() { return 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Formal
|
struct Formal
|
||||||
|
@ -252,6 +267,7 @@ struct ExprLambda : Expr
|
||||||
string showNamePos() const;
|
string showNamePos() const;
|
||||||
inline bool hasFormals() const { return formals != nullptr; }
|
inline bool hasFormals() const { return formals != nullptr; }
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
|
Pos* getPos() { return &pos; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ExprCall : Expr
|
struct ExprCall : Expr
|
||||||
|
@ -263,6 +279,7 @@ struct ExprCall : Expr
|
||||||
: fun(fun), args(args), pos(pos)
|
: fun(fun), args(args), pos(pos)
|
||||||
{ }
|
{ }
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
|
Pos* getPos() { return &pos; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ExprLet : Expr
|
struct ExprLet : Expr
|
||||||
|
@ -271,6 +288,7 @@ struct ExprLet : Expr
|
||||||
Expr * body;
|
Expr * body;
|
||||||
ExprLet(ExprAttrs * attrs, Expr * body) : attrs(attrs), body(body) { };
|
ExprLet(ExprAttrs * attrs, Expr * body) : attrs(attrs), body(body) { };
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
|
Pos* getPos() { return 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ExprWith : Expr
|
struct ExprWith : Expr
|
||||||
|
@ -280,6 +298,7 @@ struct ExprWith : Expr
|
||||||
size_t prevWith;
|
size_t prevWith;
|
||||||
ExprWith(const Pos & pos, Expr * attrs, Expr * body) : pos(pos), attrs(attrs), body(body) { };
|
ExprWith(const Pos & pos, Expr * attrs, Expr * body) : pos(pos), attrs(attrs), body(body) { };
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
|
Pos* getPos() { return &pos; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ExprIf : Expr
|
struct ExprIf : Expr
|
||||||
|
@ -288,6 +307,7 @@ struct ExprIf : Expr
|
||||||
Expr * cond, * then, * else_;
|
Expr * cond, * then, * else_;
|
||||||
ExprIf(const Pos & pos, Expr * cond, Expr * then, Expr * else_) : pos(pos), cond(cond), then(then), else_(else_) { };
|
ExprIf(const Pos & pos, Expr * cond, Expr * then, Expr * else_) : pos(pos), cond(cond), then(then), else_(else_) { };
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
|
Pos* getPos() { return &pos; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ExprAssert : Expr
|
struct ExprAssert : Expr
|
||||||
|
@ -296,6 +316,7 @@ struct ExprAssert : Expr
|
||||||
Expr * cond, * body;
|
Expr * cond, * body;
|
||||||
ExprAssert(const Pos & pos, Expr * cond, Expr * body) : pos(pos), cond(cond), body(body) { };
|
ExprAssert(const Pos & pos, Expr * cond, Expr * body) : pos(pos), cond(cond), body(body) { };
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
|
Pos* getPos() { return &pos; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ExprOpNot : Expr
|
struct ExprOpNot : Expr
|
||||||
|
@ -303,6 +324,7 @@ struct ExprOpNot : Expr
|
||||||
Expr * e;
|
Expr * e;
|
||||||
ExprOpNot(Expr * e) : e(e) { };
|
ExprOpNot(Expr * e) : e(e) { };
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
|
Pos* getPos() { return 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MakeBinOp(name, s) \
|
#define MakeBinOp(name, s) \
|
||||||
|
@ -321,6 +343,7 @@ struct ExprOpNot : Expr
|
||||||
e1->bindVars(env); e2->bindVars(env); \
|
e1->bindVars(env); e2->bindVars(env); \
|
||||||
} \
|
} \
|
||||||
void eval(EvalState & state, Env & env, Value & v); \
|
void eval(EvalState & state, Env & env, Value & v); \
|
||||||
|
Pos* getPos() { return &pos; } \
|
||||||
};
|
};
|
||||||
|
|
||||||
MakeBinOp(ExprOpEq, "==")
|
MakeBinOp(ExprOpEq, "==")
|
||||||
|
@ -339,6 +362,7 @@ struct ExprConcatStrings : Expr
|
||||||
ExprConcatStrings(const Pos & pos, bool forceString, vector<Expr *> * es)
|
ExprConcatStrings(const Pos & pos, bool forceString, vector<Expr *> * es)
|
||||||
: pos(pos), forceString(forceString), es(es) { };
|
: pos(pos), forceString(forceString), es(es) { };
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
|
Pos* getPos() { return &pos; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ExprPos : Expr
|
struct ExprPos : Expr
|
||||||
|
@ -346,6 +370,7 @@ struct ExprPos : Expr
|
||||||
Pos pos;
|
Pos pos;
|
||||||
ExprPos(const Pos & pos) : pos(pos) { };
|
ExprPos(const Pos & pos) : pos(pos) { };
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
|
Pos* getPos() { return &pos; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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::ostream & showErrorInfo(std::ostream & out, const ErrorInfo & einfo, bool showTrace)
|
||||||
{
|
{
|
||||||
|
std::cout << "showErrorInfo showTrace: " << showTrace << std::endl;
|
||||||
|
|
||||||
std::string prefix;
|
std::string prefix;
|
||||||
switch (einfo.level) {
|
switch (einfo.level) {
|
||||||
case Verbosity::lvlError: {
|
case Verbosity::lvlError: {
|
||||||
|
|
|
@ -38,6 +38,7 @@ typedef uint64_t ActivityId;
|
||||||
struct LoggerSettings : Config
|
struct LoggerSettings : Config
|
||||||
{
|
{
|
||||||
Setting<bool> showTrace{
|
Setting<bool> showTrace{
|
||||||
|
// this, false, "show-trace",
|
||||||
this, false, "show-trace",
|
this, false, "show-trace",
|
||||||
R"(
|
R"(
|
||||||
Where Nix should print out a stack trace in case of Nix
|
Where Nix should print out a stack trace in case of Nix
|
||||||
|
|
Loading…
Reference in a new issue