diff --git a/lix/libcmd/repl.cc b/lix/libcmd/repl.cc index d156deaf1..2b9eaa122 100644 --- a/lix/libcmd/repl.cc +++ b/lix/libcmd/repl.cc @@ -285,7 +285,7 @@ ReplExitStatus NixRepl::mainLoop() { if (isFirstRepl) { std::string_view debuggerNotice = ""; - if (state.debug.repl) { + if (state.debug.inDebugger) { debuggerNotice = " debugger"; } notice("Lix %1%%2%\nType :? for help.", nixVersion, debuggerNotice); @@ -366,7 +366,7 @@ StringSet NixRepl::completePrefix(const std::string & prefix) } } - if (state.debug.repl) { + if (state.debug.inDebugger) { for (auto const & colonCmd : this->DEBUG_COMMANDS) { if (colonCmd.starts_with(prefix)) { completions.insert(std::string(colonCmd)); @@ -541,7 +541,7 @@ ProcessLineResult NixRepl::processLine(std::string line) << " errors\n" << " :?, :help Brings up this help menu\n" ; - if (state.debug.repl) { + if (state.debug.inDebugger) { std::cout << "\n" << " Debug mode commands\n" @@ -556,14 +556,14 @@ ProcessLineResult NixRepl::processLine(std::string line) } - else if (state.debug.repl && (command == ":bt" || command == ":backtrace")) { + else if (state.debug.inDebugger && (command == ":bt" || command == ":backtrace")) { for (const auto & [idx, i] : enumerate(state.debug.traces)) { std::cout << "\n" << ANSI_BLUE << idx << ANSI_NORMAL << ": "; showDebugTrace(std::cout, state.positions, i); } } - else if (state.debug.repl && (command == ":env")) { + else if (state.debug.inDebugger && (command == ":env")) { for (const auto & [idx, i] : enumerate(state.debug.traces)) { if (idx == debugTraceIndex) { printEnvBindings(state, i.expr, i.env); @@ -572,7 +572,7 @@ ProcessLineResult NixRepl::processLine(std::string line) } } - else if (state.debug.repl && (command == ":st")) { + else if (state.debug.inDebugger && (command == ":st")) { try { // change the DebugTrace index. debugTraceIndex = stoi(arg); @@ -590,13 +590,13 @@ ProcessLineResult NixRepl::processLine(std::string line) } } - else if (state.debug.repl && (command == ":s" || command == ":step")) { + else if (state.debug.inDebugger && (command == ":s" || command == ":step")) { // set flag to stop at next DebugTrace; exit repl. state.debug.stop = true; return ProcessLineResult::Continue; } - else if (state.debug.repl && (command == ":c" || command == ":continue")) { + else if (state.debug.inDebugger && (command == ":c" || command == ":continue")) { // set flag to run to next breakpoint or end of program; exit repl. state.debug.stop = false; return ProcessLineResult::Continue; diff --git a/tests/functional/repl_characterization/data/debug_frames.test b/tests/functional/repl_characterization/data/debug_frames.test new file mode 100644 index 000000000..25e28ef97 --- /dev/null +++ b/tests/functional/repl_characterization/data/debug_frames.test @@ -0,0 +1,73 @@ +@args --debugger + +:c at the root repl is not allowed since no debugger is running yet + nix-repl> :c + error: unknown command ':c' + +:c and other commands become available once a debugger starts + nix-repl> with {}; a + error: undefined variable 'a' + at «string»:1:10: + 1| with {}; a + | ^ + + nix-repl> :? + The following commands are available: + + Evaluate and print expression + = Bind expression to variable + :a, :add Add attributes from resulting set to scope + :b Build a derivation + :bl Build a derivation, creating GC roots in the + working directory + :e, :edit Open package or function in $EDITOR + :i Build derivation, then install result into + current profile + :l, :load Load Nix expression and add it to scope + :lf, :load-flake Load Nix flake and add it to scope + :p, :print Evaluate and print expression recursively + Strings are printed directly, without escaping. + :q, :quit Exit nix-repl + :r, :reload Reload all files + :sh Build dependencies of derivation, then start + nix-shell + :t Describe result of evaluation + :u Build derivation, then start nix-shell + :doc Show documentation for the provided function (experimental lambda support) + :log Show logs for a derivation + :te, :trace-enable [bool] Enable, disable or toggle showing traces for + errors + :?, :help Brings up this help menu + + Debug mode commands + :env Show env stack + :bt, :backtrace Show trace stack + :st Show current trace + :st Change to another trace in the stack + :c, :continue Go until end of program, exception, or builtins.break + :s, :step Go one step + +we can now inspect state + nix-repl> :bt + 0: error: undefined variable 'a' + «string»:1:10 + + 1| with {}; a + | ^ + + 1: error: Fake frame for debugging purposes + «string»:1:10 + + 1| with {}; a + | ^ + +and resume execution + nix-repl> :c + error: undefined variable 'a' + at «string»:1:10: + 1| with {}; a + | ^ + +the debugger is once again disabled + nix-repl> :c + error: unknown command ':c' diff --git a/tests/functional/repl_characterization/repl_characterization.cc b/tests/functional/repl_characterization/repl_characterization.cc index f7e5e62b2..7e33ecec0 100644 --- a/tests/functional/repl_characterization/repl_characterization.cc +++ b/tests/functional/repl_characterization/repl_characterization.cc @@ -186,5 +186,6 @@ REPL_TEST(repl_printing); REPL_TEST(stack_vars); REPL_TEST(errors); REPL_TEST(idempotent); +REPL_TEST(debug_frames); }; // namespace nix