stack traces basically working

This commit is contained in:
Ben Burdette 2021-12-22 19:40:08 -07:00
parent b4a59a5eec
commit bc20e54e00
3 changed files with 78 additions and 17 deletions

View file

@ -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()) {

View file

@ -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);

View file

@ -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;