2

i was wondering if there is any way of tracking an infinite loop in javascript/jquery ?

I am working on a jsTree plugin clone sort of.. (why isn't important) and I've create a infinite loop somewhere and i am trying to track where it happened. i thought maybe there are browser specific tricks to track infinite loops

E.G

<div id="someAwesomeDiv"></div>

jQuery(document).ready(function ($) {
    var i = 0;
    while(i < 10){
        console.log(i);
        $('#someAwesomeDiv').append('<br>i</br>')
        i--;
    }
});

when i refresh this page.. nothing is appended to the div nor does it console.logged, the page just freezes.

Thanks in advanced.

Neta Meta
  • 4,001
  • 9
  • 42
  • 67
  • What browser are you using? In Chrome, for me, the console logging *usually* works when I take your existing code and paste it into a jsfiddle, although it comes through large batches of lines at a time and sometimes the tab hangs completely and the console dies. Anyway, what are you trying to achieve here? *Locating* an infinite loop in some real code (that you know is hanging, but you don't know where), or just recording each pass through something that you already know is an infinite loop? I can't see why you'd want to do the latter - why not fix the loop instead? – Mark Amery Jun 09 '13 at 13:10
  • I am trying to locate how the loop happens its a part of a much larger code. i thought there going to be an easy way maybe a hidden firebug trick or something. but i guess i will just have to continue checking – Neta Meta Jun 09 '13 at 13:12

2 Answers2

1

That is the supposed behaviour. Your are cogging the JS engine with your infinite loop, it's busy doing that rather then rendering (both page and console in dev tool window).

namero999
  • 2,882
  • 18
  • 24
  • So there's no way of tracking it ? – Neta Meta Jun 09 '13 at 12:58
  • Try to insert `setInterval` to split your loop and give the browser some rest to do other stuff. Just an idea, you should try. – namero999 Jun 09 '13 at 13:00
  • @namero999 setTimeout doesn't work break in other languages. It only pushed an async event to the event stack. And doesn't prevent the infinity loop to continue. – Andreas Louv Jun 09 '13 at 13:00
  • Any other idea other then setInterval ? – Neta Meta Jun 09 '13 at 13:04
  • Forking V8 and implement this behaviour :) – namero999 Jun 09 '13 at 13:04
  • Why it happens is clear. The main thread of your process is 100% busy in the loop. The `console.log` is actually executed, but the process is not even able to refresh your console for you to see the message or the page for you to see the elements. You have to break your loop and let the engine breathe for some time in between. – namero999 Jun 09 '13 at 13:12
0

If you're having difficulty finding and diagnosing infinite loops by throwing console.log calls into all your suspect loops, try using alert and confirm instead. While console.log can be somewhat uncooperative (or, by the sounds of it, completely non-functional) when the browser is stuck in an infinite loop, alert will always work immediately.

With confirm, you can even go one step better and have the option of breaking out of the loop. For example, here is your example code modified to let you break out of the loop at any time.

jQuery(document).ready(function ($) {
    var i = 0;
    while(i < 10){
        if (confirm("i = " + i + "; break the loop?")) {
          throw new Error("Loop broken by manual user override");
        }
        $('#someAwesomeDiv').append('<br>i</br>')
        i--;
    }
});

(Fiddle).

Then if you hit the infinite loop, you can choose to throw an error and hopefully (unless it gets caught, or the same code is immediately triggered again) regain control of the window and be left free to play around in the window and the console and try to figure out what was going on the cause the loop.

Two word of caution, though: in some browsers, alert and confirm can sometimes make weird stuff happen in your code by screwing up the expected order of execution when, for instances, DOM events get triggered during an alert, as bobince describes in detail here: https://stackoverflow.com/a/2734311/1709587. They can potentially help you in infinite loops where console.log is trickier to wield, but make sure you don't get tripped up by behavior changes introduced by putting alerts into your code. Also note that reflows happen when you trigger an alert, which can change the behavior of code involving CSS transitions.

Also, I'm really not sure why you're not getting any output in the console from the sample code you've given. When I paste it into a jsFiddle and try it on Chrome, and then load the fiddle with the console open, the page is slow and unkillable and the whole browser a little buggered, but I do see things being logged (admittedly only every thousand lines or so). In Firefox, nothing happens for 5 seconds or so, but then I get an 'unresponsive page' popup and the option to kill the running script - after which I can see everything that was logged in the console. Perhaps trying a different browser (or the latest version of whatever browser you use) will make life easier for you without needing to deploy any tricks?

Community
  • 1
  • 1
Mark Amery
  • 143,130
  • 81
  • 406
  • 459