Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Firefox forget value of variable? Solution for debugging?

Steps:

  1. Open page in Firefox 29.0.1 (Windows 7 x64):

    <!doctype html>
    <title>Test</title>
    <script>
        (function () {
            var x = 5, f = function () {
                setTimeout(f, 1000);
            };
            f();
        }());
    </script>
    
  2. Open Developer Tools (F12).

  3. In the Debugger, set a breakpoint on: setTimeout(f, 1000);

  4. Once the breakpoint is hit, evaluate x in the console. The result: undefined

    Screenshot showing when <code>x</code> is evaluated

  5. Reload the page. The breakpoint is hit on the first run of f.

  6. Evaluate x. The result: 5

  7. Resume execution, and when the breakpoint is hit again, evaluate x. Same result: 5

My assumption: If Firefox realizes on the first run of f that x is not needed, then it doesn't store the value of x "with" f. So in subsequent calls to f the value of x is undefined. Interestingly, I see the same behavior in Chrome 35 and IE11.

Question: What is going on? Can I configure Firefox to make x evaluate to its correct value in step 4 (see above)?

like image 697
feklee Avatar asked Jun 05 '14 20:06

feklee


1 Answers

It seems your assumption is correct. The problem is that the variable has been optimised out or removed when the debugger wasn't running. When you refresh the page with the debugger running, it alllows you to access the inner scopes of functions so that you can debug your code more easily.

This wouldn't be possible if there wasn't a breakpoint there, so the JIT compiler has to be disabled to let you do so. The garbage collector also notes that these can still be referenced in-scope, so doesn't remove these variables.

If the JIT compiler was running, it would recognise that the x variable is not used anywhere and remove that from the code generated. If the JIT compiler was not running, garbage collection (GC) would remove the variable when the GC cycle runs, as there is nothing referencing the variable.

Because it can't undo what it's already done, it is undefined when you hit the breakpoint the first time.

You can't really prevent this occuring, even if you disable the JIT compiler. While technically you could set the garbage collection limits really high to try and stop it doing so or even remove the garbage collection code and rebuild Firefox, that's pretty stupid -- you'd just end up leaking a bunch of memory and that'd be much more hassle than simply refreshing the page.

Interestingly though, Firefox 31 (Aurora) provides a more descriptive error message if you try and do the same thing:

Error: variable has been optimized out
like image 121
Qantas 94 Heavy Avatar answered Sep 20 '22 00:09

Qantas 94 Heavy