Skip to content Skip to sidebar Skip to footer

How Do I Go Into Eval('debugger') Mode When Already Stopped At 'regular' Debugger Statement?

I recently started to swap out all my debugger statements with eval('debugger') statements. The reason is that with the plain version, not all 'factually/theoretically' visible var

Solution 1:

V8 developer here.

Is there a way to tell v8 to interpret all debugger statements by eval('debugger')?

There is currently no way to treat debugger statements or breakpoints as eval("debugger"), but it might be feasible to add a flag that does this. You can file a "feature request" bug at crbug.com/v8/new and ask for a flag that forcibly context-allocates all variables for debugging purposes.

(Side note 1: It's the eval part that has an effect here. Instead of eval('debugger') you could write eval(""); debugger; or debugger; other_code(); eval("");, so long as you have eval somewhere in the function.)

(Side note 2: the tension here is that on the one hand, it's Good™ when the behavior of a program when it is being debugged is the same as when it is not being debugged -- otherwise there might be issues that only show up when debugging, or un-debuggable failures in production mode. On the other hand, sometimes certain deviations are explicitly necessary in order to make debugging possible. I'm not sure on which side of the line this one falls. Context-allocating all variables will reduce performance and increase memory consumption, so if/when such a mode becomes available, you will probably have to (or want to) switch back and forth during your development work; which in particular means that this couldn't simply be the default when DevTools are open.)

Is there a trick with which you can 'go into the other mode' - as if the eval('debugger') statement would magically appear as the next statement after the debugger statement where you're stopped?

No, and there can't be. It's not a "mode" or "special status", it's a decision that has to be made when first parsing/compiling the outer function (the one that contained the variable you want to see within an inner function). Once that time has passed, it's too late to change anything (non-context-allocated variables are just gone), and the only option is to reload.

[EDIT in response to comments: To clarify what I mean by "not a mode, but a decision": from the scope chain's point of view, the situation is essentially the same as:

var inner;
function outer() {
  var foo = "foo";
  var bar = "bar";
  inner = function() {
    console.log(bar);
    debugger;
  }
  // "inner();" here is moved below
}
outer();
inner();

at the point when inner() is called, foo is either still there like bar (if it's context-allocated because at compile time of outer V8 determined that inner will need it), or gone (if V8 determined that it's local to outer and nobody else will need it). If inner contains eval, then it might need all outer-scope variables. --end of EDIT]

This happens because of optimization

Well... because of an optimization, namely being smart about whether to allocate variables on the stack or in the "context object". This is completely unrelated to what is typically referred to as "optimization of a function", i.e. running them through the optimizing compiler. That's why the %NeverOptimizeFunction hack discussed in the other issue had no effect -- it's an unrelated mechanism.


Post a Comment for "How Do I Go Into Eval('debugger') Mode When Already Stopped At 'regular' Debugger Statement?"