mirror of
https://github.com/privatevoid-net/nix-super.git
synced 2025-01-19 17:46:46 +02:00
Merge pull request #9920 from 9999years/forbid-nested-debuggers
Forbid nested debuggers
This commit is contained in:
commit
e164b39ee9
5 changed files with 53 additions and 12 deletions
32
doc/manual/rl-next/forbid-nested-debuggers.md
Normal file
32
doc/manual/rl-next/forbid-nested-debuggers.md
Normal file
|
@ -0,0 +1,32 @@
|
|||
---
|
||||
synopsis: Nested debuggers are no longer supported
|
||||
prs: 9920
|
||||
---
|
||||
|
||||
Previously, evaluating an expression that throws an error in the debugger would
|
||||
enter a second, nested debugger:
|
||||
|
||||
```
|
||||
nix-repl> builtins.throw "what"
|
||||
error: what
|
||||
|
||||
|
||||
Starting REPL to allow you to inspect the current state of the evaluator.
|
||||
|
||||
Welcome to Nix 2.18.1. Type :? for help.
|
||||
|
||||
nix-repl>
|
||||
```
|
||||
|
||||
Now, it just prints the error message like `nix repl`:
|
||||
|
||||
```
|
||||
nix-repl> builtins.throw "what"
|
||||
error:
|
||||
… while calling the 'throw' builtin
|
||||
at «string»:1:1:
|
||||
1| builtins.throw "what"
|
||||
| ^
|
||||
|
||||
error: what
|
||||
```
|
|
@ -336,12 +336,6 @@ ReplExitStatus NixRepl::mainLoop()
|
|||
printMsg(lvlError, e.msg());
|
||||
}
|
||||
} catch (EvalError & e) {
|
||||
// in debugger mode, an EvalError should trigger another repl session.
|
||||
// when that session returns the exception will land here. No need to show it again;
|
||||
// show the error for this repl session instead.
|
||||
if (state->debugRepl && !state->debugTraces.empty())
|
||||
showDebugTrace(std::cout, state->positions, state->debugTraces.front());
|
||||
else
|
||||
printMsg(lvlError, e.msg());
|
||||
} catch (Error & e) {
|
||||
printMsg(lvlError, e.msg());
|
||||
|
|
|
@ -762,10 +762,24 @@ std::unique_ptr<ValMap> mapStaticEnvBindings(const SymbolTable & st, const Stati
|
|||
return vm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets `inDebugger` to true on construction and false on destruction.
|
||||
*/
|
||||
class DebuggerGuard {
|
||||
bool & inDebugger;
|
||||
public:
|
||||
DebuggerGuard(bool & inDebugger) : inDebugger(inDebugger) {
|
||||
inDebugger = true;
|
||||
}
|
||||
~DebuggerGuard() {
|
||||
inDebugger = false;
|
||||
}
|
||||
};
|
||||
|
||||
void EvalState::runDebugRepl(const Error * error, const Env & env, const Expr & expr)
|
||||
{
|
||||
// double check we've got the debugRepl function pointer.
|
||||
if (!debugRepl)
|
||||
// Make sure we have a debugger to run and we're not already in a debugger.
|
||||
if (!debugRepl || inDebugger)
|
||||
return;
|
||||
|
||||
auto dts =
|
||||
|
@ -792,6 +806,7 @@ void EvalState::runDebugRepl(const Error * error, const Env & env, const Expr &
|
|||
auto se = getStaticEnv(expr);
|
||||
if (se) {
|
||||
auto vm = mapStaticEnvBindings(symbols, *se.get(), env);
|
||||
DebuggerGuard _guard(inDebugger);
|
||||
auto exitStatus = (debugRepl)(ref<EvalState>(shared_from_this()), *vm);
|
||||
switch (exitStatus) {
|
||||
case ReplExitStatus::QuitAll:
|
||||
|
|
|
@ -153,6 +153,7 @@ struct DebugTrace {
|
|||
bool isError;
|
||||
};
|
||||
|
||||
|
||||
class EvalState : public std::enable_shared_from_this<EvalState>
|
||||
{
|
||||
public:
|
||||
|
@ -222,6 +223,7 @@ public:
|
|||
*/
|
||||
ReplExitStatus (* debugRepl)(ref<EvalState> es, const ValMap & extraEnv);
|
||||
bool debugStop;
|
||||
bool inDebugger = false;
|
||||
int trylevel;
|
||||
std::list<DebugTrace> debugTraces;
|
||||
std::map<const Expr*, const std::shared_ptr<const StaticEnv>> exprEnvs;
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
namespace nix {
|
||||
|
||||
namespace {
|
||||
/**
|
||||
* A helper for writing `boost::format` expressions.
|
||||
*
|
||||
|
@ -35,14 +34,13 @@ inline void formatHelper(F & f, const T & x, const Args & ... args)
|
|||
/**
|
||||
* Set the correct exceptions for `fmt`.
|
||||
*/
|
||||
void setExceptions(boost::format & fmt)
|
||||
inline void setExceptions(boost::format & fmt)
|
||||
{
|
||||
fmt.exceptions(
|
||||
boost::io::all_error_bits ^
|
||||
boost::io::too_many_args_bit ^
|
||||
boost::io::too_few_args_bit);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A helper for writing a `boost::format` expression to a string.
|
||||
|
|
Loading…
Reference in a new issue