forked from lix-project/lix
stack traces basically working
This commit is contained in:
parent
b4a59a5eec
commit
bc20e54e00
|
@ -448,6 +448,26 @@ bool NixRepl::processLine(string line)
|
||||||
else if (command == ":d" || command == ":debug") {
|
else if (command == ":d" || command == ":debug") {
|
||||||
std::cout << "debug: '" << arg << "'" << std::endl;
|
std::cout << "debug: '" << arg << "'" << std::endl;
|
||||||
if (arg == "stack") {
|
if (arg == "stack") {
|
||||||
|
std::cout << "eval stack:" << std::endl;
|
||||||
|
for (auto iter = this->state->debugTraces.begin();
|
||||||
|
iter != this->state->debugTraces.end(); ++iter) {
|
||||||
|
std::cout << "\n" << "… " << iter->hint.str() << "\n";
|
||||||
|
|
||||||
|
if (iter->pos.has_value() && (*iter->pos)) {
|
||||||
|
auto pos = iter->pos.value();
|
||||||
|
std::cout << "\n";
|
||||||
|
printAtPos(pos, std::cout);
|
||||||
|
|
||||||
|
auto loc = getCodeLines(pos);
|
||||||
|
if (loc.has_value()) {
|
||||||
|
std::cout << "\n";
|
||||||
|
printCodeLines(std::cout, "", pos, *loc);
|
||||||
|
std::cout << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (arg == "error") {
|
else if (arg == "error") {
|
||||||
if (this->debugError.has_value()) {
|
if (this->debugError.has_value()) {
|
||||||
|
|
|
@ -38,6 +38,23 @@ namespace nix {
|
||||||
|
|
||||||
std::function<void(const Error & error, const Env & env, const Expr & expr)> debuggerHook;
|
std::function<void(const Error & error, const Env & env, const Expr & expr)> debuggerHook;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
static char * dupString(const char * s)
|
static char * dupString(const char * s)
|
||||||
{
|
{
|
||||||
char * t;
|
char * t;
|
||||||
|
@ -1110,23 +1127,6 @@ 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 {
|
// class DebugTraceStacker {
|
||||||
// DebugTraceStacker(std::ref<EvalState> evalState, std::ref<Trace> t)
|
// DebugTraceStacker(std::ref<EvalState> evalState, std::ref<Trace> t)
|
||||||
// :evalState(evalState), trace(t)
|
// :evalState(evalState), trace(t)
|
||||||
|
@ -1387,6 +1387,17 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v)
|
||||||
e->eval(state, env, vTmp);
|
e->eval(state, env, vTmp);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
std::unique_ptr<DebugTraceStacker> dts =
|
||||||
|
debuggerHook ?
|
||||||
|
std::unique_ptr<DebugTraceStacker>(
|
||||||
|
new DebugTraceStacker(
|
||||||
|
state,
|
||||||
|
Trace { .pos = *pos2,
|
||||||
|
.hint = hintfmt(
|
||||||
|
"while evaluating the attribute '%1%'",
|
||||||
|
showAttrPath(state, env, attrPath))
|
||||||
|
}))
|
||||||
|
: std::unique_ptr<DebugTraceStacker>();
|
||||||
|
|
||||||
for (auto & i : attrPath) {
|
for (auto & i : attrPath) {
|
||||||
state.nrLookups++;
|
state.nrLookups++;
|
||||||
|
@ -1530,6 +1541,21 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value &
|
||||||
|
|
||||||
/* Evaluate the body. */
|
/* Evaluate the body. */
|
||||||
try {
|
try {
|
||||||
|
std::unique_ptr<DebugTraceStacker> dts =
|
||||||
|
debuggerHook ?
|
||||||
|
std::unique_ptr<DebugTraceStacker>(
|
||||||
|
new DebugTraceStacker(
|
||||||
|
*this,
|
||||||
|
Trace { .pos = lambda.pos,
|
||||||
|
.hint = hintfmt(
|
||||||
|
"while evaluating %s",
|
||||||
|
(lambda.name.set()
|
||||||
|
? "'" + (string) lambda.name + "'"
|
||||||
|
: "anonymous lambda"))
|
||||||
|
}))
|
||||||
|
: std::unique_ptr<DebugTraceStacker>();
|
||||||
|
|
||||||
|
|
||||||
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;
|
std::cout << "eval showErrorInfo showTrace: " << loggerSettings.showTrace.get() << std::endl;
|
||||||
|
@ -1924,6 +1950,18 @@ 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 =
|
||||||
|
debuggerHook ?
|
||||||
|
std::unique_ptr<DebugTraceStacker>(
|
||||||
|
new DebugTraceStacker(
|
||||||
|
*this,
|
||||||
|
Trace { .pos = *i.pos,
|
||||||
|
.hint = hintfmt(
|
||||||
|
"while evaluating the attribute '%1%'", i.name)
|
||||||
|
}))
|
||||||
|
: std::unique_ptr<DebugTraceStacker>();
|
||||||
|
|
||||||
|
|
||||||
recurse(*i.value);
|
recurse(*i.value);
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
addErrorTrace(e, *i.pos, "while evaluating the attribute '%1%'", i.name);
|
addErrorTrace(e, *i.pos, "while evaluating the attribute '%1%'", i.name);
|
||||||
|
|
|
@ -106,6 +106,9 @@ void printCodeLines(std::ostream & out,
|
||||||
const ErrPos & errPos,
|
const ErrPos & errPos,
|
||||||
const LinesOfCode & loc);
|
const LinesOfCode & loc);
|
||||||
|
|
||||||
|
void printAtPos(const ErrPos & pos, std::ostream & out);
|
||||||
|
|
||||||
|
|
||||||
struct Trace {
|
struct Trace {
|
||||||
std::optional<ErrPos> pos;
|
std::optional<ErrPos> pos;
|
||||||
hintformat hint;
|
hintformat hint;
|
||||||
|
|
Loading…
Reference in a new issue