How to identify and terminate a javascript in infinite loop programmatically? - javascript

It is more of a hypothetical question. There is sometimes a possibility of a javascript code entering an infinite loop and blocking everything specially in early stages of development. I know the best solution would be to code so that such a situation never arises but what if in a certain case it is impossible to write a fullproof code (maybe because we don't have control on the input or something else).
Is there any way we can programmatically determine when a code is in an infinite loop and terminate it?
Maybe running the pieces of code where such a thing could happen in a separate thread or in a child process synchronously and determining when that thread/process is in an infinite loop.
How could one go about doing that? Is it possible to determine when a thread (either main or child) is in an infinite loop by determining the CPU usage by that thread alone?
Based on the discussion had in comments below I realise that identifying a blocking infinite loop would be impossible on the basis of tracking repetitive execution of similar statements and high resource utilization alone. So I think that the solution lies in a combination of both. But that brings as back to our earlier problem. How can we gauge the CPU usage by a script?

For simple loops you can use approach used here . It uses path based approach to detect infinite loop. Statements are considered as nodes of graph.
You can also see this paper. They have implemented run time solution for java program.

Given there are no other viable/sophisticated solutions proposed, a low-tech solution is to just use a counter and abort if it reaches an absurdly high number.
This requires manual coding effort, but can be useful for debugging an infinite loop when you know it is already happening.
var count = 0
while(true){
if(count++>100000){
//assume infinite loop, exit to avoid locking up browser while debugging
break;
}
}

Related

JavaScript: trying to create a well-behaved background job, but it gets too little time to run while rest of the system is mostly idle?

In a browser, I am trying to make a well-behaved background job like this:
function run() {
var system = new System();
setInterval(function() { system.step(); }, 0);
}
It doesn't matter what that System object is or what the step function does [except it needs to interact with the UI, in my case, update a canvas to run Conway's Game of Life in the background], the activity is performed slowly and I want it to run faster. But I already specified no wait time in the setInterval, and yet, when I check the profiling tool in Chrome it tells me the whole thing is 80% idle:
Is there a way to make it do less idle time and perform my job more quickly on a best effort basis? Or do I have to make my own infinite loop and then somehow yield back time to the event loop on a regular basis?
UPDATE: It was proposed to use requestIdleCallback, and doing that makes it actually worse. The activity is noticably slower, even if the profiling data isn't very obvious about it, but indeed the idle time has increased:
UPDATE: It was then proposed to use requestAnimationFrame, and I find that once again the slowness and idleness is the same as the requestIdleCallback method, and both run at about half the speed that I get from the standard setInterval.
PS: I have updated all the timings to be comparable, all three now timing about 10 seconds of the same code running. I had the suspicion that perhaps the recursive re-scheduling might be the cause for the greater slowness, but I ruled that out, as the recursive setTimeout call is about the same speed as the setInterval method, and both are about twice as fast as these new request*Callback methods.
I did find a viable solution for what I'm doing in practice, and I will provide my own answer later, but will wait for a moment longer.
OK, unless somebody comes with another answer this here would be my FINAL UPDATE: I have once again measured all 4 options and measured the elapsed time to complete a reasonable chunk of work. The results are here:
setTimeout - 31.056 s
setInterval - 23.424 s
requestIdleCallback - 68.149 s
requestAnimationFrame - 68.177 s
Which provides objective data to my impression above that the two new methods with request* will perform worse.
I also have my own practical solution which allows me to complete the same amount of work in 55 ms (0.055 s), i.e., > 500 times faster, and still be relatively well behaved. Will report on that in a while. But wonder what anybody else can figure out here?
I think this is really dependent on what exactly you are trying to achieve though.
For example, you could initialize your web-worker on loading the page and make it run the background-job, if need be, then communicate the progress or status of the job to the main thread of your browser. If you don't like the use of post-message for communication between the threads, consider user Comlink
Web worker
Comlink
However, if the background job you intend to do isn't something worth a web-worker. You could use the requestIdleCallback API. I think it fits perfectly with what you mentioned here since you can already make it recursive. You would not need a timer anymore and the browser can help you schedule the task in such a way that it doesn't affect the rendering of your page (by keeping everything with 60fps).
Something like =>
function run() {
// whatever you want to keep doing
requestIdleCallback(run)
}
You can read more about requestIdleCallback on MDN.
OK, I really am not trying to prevent others to get the bounty, but as you can see from the details I added to my question, none of these methods allow high rate execution of the callback.
In principle the setInterval is the most efficient way to do it, as we already do not need to re-schedule the next call back all the time. But it is a small difference only. Notably requestIdleCallback and requestAnimationFrame are the worst when you want to be rapidly called back.
So, what needs to be done is instead of executing only a tiny amount of work and then expect to be called back quickly, we need to batch up more work. Problem is we don't know exactly how much work we should batch up before it is too much. That can probably in most cases be figured out with trial and error.
Dynamically one might take timing probes to find out how quickly we are being called back again and preemptively exit the work (loop of some kind) when the time between the call-backs is expired.

Javascript for loop never ends (10^10 itenerations)

I have a 'for' loop wich have to loop around 10000000000 times so that i get the disered result.
However, it ends up all the time freezing the browser ...
It's not like that 'for' is working infinitly but as i told, it's very long
Is there some way to solve my problem with javascript or i should use another language ?
In a compiled language and if you do virtually nothing in the loop, you can achieve 1,000,000,000 iterations a second on a desktop processor. So your loop would take 10 seconds.
If your Javascript environment is interpreted (and not compiled), you probably won't get more than 10,000,000 iterations and your loop will take 1000 seconds (16 minutes).
If you additionally have somewhat more expensive operations within the loop (and Javascript is likely to allocate memory for simple operations, which is expensive), you're in the order of 1,000,000 iterations per seconds and your code takes 10,000 seconds (close to 3 hours).
You might want to think about a better algorithm...
The issue that you are seeing is because javascript is single threaded in the browser. Your for loop is holding on to the thread for the entire time that it is running. The problem is that this thread also handles interactions with the interface. There may be other possibilities, but the two ways that I can think of to fix this would be:
Use a Web Worker (docs), this solution will not work for older browsers though
If possible, break your loop into smaller chunks that can be ran using setTimeout. After each chunk is processed, use setTimeout to schedule the next chunk to be processed in say 100ms. You will need to play with the numbers, but that should free up the thread so that it can respond to events. This will make the calculation take longer but should make it so the browser doesn't freeze up.
Don't do it. To run this kind of Javascript code in a browser makes no sense. If you really want to do this on the client side, you should consider writing some kind of browser extension, where you have more control on the CPU and local storage.
You might want to separate that loop in smaller chunks and run them sequentially, with an appropriate progress system. If you are talking about a loop, a multithreaded system will not help you, assuming the result n+1 is based on the n result.
Consider using a server-side script with a queue or job mechanism and just push notifications to the client. As Teemu said, the time (even in a fast paced situation) is huge.

Is it possible to implement a sleep() in javascript?

This is a duplicate question. It has been asked many times before, with dozens of answers, some of them rated very highly. Unfortunately, as far as I have been able to tell, every single one of those answers is a variant of "You don't, it's bad programming practice. Use setTimeout instead".
This is Not. An. Answer!
There are some use cases - rare but they exist - where you might want the entire page's execution to halt for a second or two, and I find it very frustrating that nobody seems interested in answering the actual question. (have a look at the comments here for some examples).
I am sure it's possible to halt javascript executing; for instance, if I use firebug to insert a breakpoint, then the execution stops when it hits that point. So, firebug can do it. Is there some way that the program can halt execution of the current thread until some timeout occurs?
Just some thoughts: How does firebug do it? Is there some browser-specific method? Is it possible to trigger a stop, without specifying a timeout to continue? Could I programmatically insert a breakpoint, or remove one? Could I get a closure representing the current thread to pass to setTimeout?
I don't have a specific use case in mind; I am just looking for advise from someone who knows the browser/javascript design better than me, as to how this can most effectively be done.
So far, I have come up with only one solution:
endtime=Date.now()+1000;
while(Date.now() < endtime)
$.ajax(window.location.origin,{'async':false});
This appears to work. The problem with it is, it makes hundreds of excess requests. I would replace the location.origin with something like mysite/sleep?delay=X and write a server side script to provide the delay, which would but it down to one, but the whole thing still seems really hacky. There must be a better way to do this! How does the jquery.ajax function manage it? Or is there a busy-wait buried in it somewhere?
The following do not answer the question and will be downvoted, just because I am sick of seeing pages of answers that completely ignore the question in their rush to rant on the evils of sleep:
Sleep is evil, and you should do anything it takes to avoid needing it.
Refactor your code so that you can use setTimeout to delay execution.
Busy-wait (because it doesn't stop execution for the duration of the sleep).
Refactor your code to use deferred/promise semantics.
You should never do this, it's a bad idea...
... because the browser has been, traditionally, single-threaded. Sleeping freezes the UI as well as the script.
However, now that we have web workers and the like, that's not the case. You probably don't need a sleep, but having a worker busy-wait won't freeze the UI. Depending on just how much you want to freeze a particular thread, I've seen people use:
endtime = Date.now()+1000;
while (Date.now() < endtime)
or, curiously (this was in an older but corporate-sponsored analytics library):
endtime = new Date().getTime() + 1000;
while (new Date().getTime() < endtime)
which is probably slower. If you're running a busy wait, that doesn't necessarily matter, and allocating objects probably just burns memory and GC time.
Code using promises or timeouts tends to be more modular, but harder to read (especially when you first learn async techniques). That's not an excuse for not using it, as there are definite advantages, but maybe you need everything to stay synchronous for some reason.
If you have a debugger running and want some chunk of code to pause itself (very useful when you have a bunch of nested callbacks), you can use:
function foo() {
do.someStuff();
debugger;
do.otherStuff();
}
The browser should pause execution at the debugger statement. The debugger can almost always pause execution, because it is in control of the VM running the code; it can just tell the VM to stop running, and that ought to happen. You can't get quite to that level from a script, but if you take source as text (perhaps from a require.js plugin), you can modify it on the fly to include debugger statements, thus "programmatically inserting breakpoints." Bear in mind that they will only take effect when the debugger is already open, though.
To capture the state of a "thread" and persist it for later use, you may want to look into some of the more complicated functional programming concepts, particularly monads. These allow you to wrap a start value in a chain of functions, which modify it as they go, but always in the same way. You could either keep simple state (in some object), or record and reproduce everything the "thread" may have done by wrapping functions in functions. There will be performance implications, but you can pick up the last function later and call it, and you should be able to reproduce everything the thread may have done.
Those are all fairly complicated and specific-use solutions to avoid just deferring things idiomatically, but if you hypothetically need them, they could be useful.
No, it is not possible to implement a sleep in javascript in the traditional sense, as it is a single-threaded event based model. The act of sleeping this thread will lock up the browser it is running in and the user is presented with a message either telling them the browser has stopped responding (IE) or allowing them to abort the currently running code (Firefox).

Two JavaScript timers vs one timer, for performance, is it worth dropping one?

In a web app which I'm building, I have two loosely related bits of code running in two separate timers every one second.
I'm looking to optimize the Javascript, is it worth merging these two timers into one or is that just over the top?
Realistically, am I going to increase any performance (considering that we don't know what sort a system a visitor is running ) by merging two 1 second intervals into one 1 second interval?
As I understand it, JavaScript is single threaded so the more things happening, the more these stack up and block other things from happening (timers especially). I just don't know whether one measly timer running every second is an issue at all.
The reason for keeping the two timers separate would purely be code readability, which is fine on the server side where you control the hardware but I don't know what sort of browser or hardware my visitors will be running.
Thanks.
In terms of the overall number of operations that can be completed, no, there isn't going to be a measurable difference. It is possible for there to be a perceived performance advantage in keeping multiple timers, however. The more code you have running synchronously in a single timer iteration, the longer all DOM updates and certain types of user interactions are "halted". By splitting these up into multiple timers, you allow other updates to take place in between timer iterations, and therefore the user gets a "smoother" experience.
Odds are in this case there won't even be a difference in perceived performance either, though, so I'd do it whichever way makes the code organization simpler.
If performance really is an issue you could just create 1 timer, and for example use that to call both functions:
function update()
{
A(); //Do your first task
B(); //Do the second
setTimeout("update()", 1000);
}
update();
However, how sure are you that the bottleneck is within this timer? Try to measure first, and dont optimise the wrong parts of your application.
I would bet that you'd increase performance by eliminating clock handling at the JS level. You certainly won't degrade performance and, with just one timer running, I'd think that you'd enhance code maintainability, if not readability. In the app I'm working on right now, I have one timer running to handle three tasks: a special kind of scrolling, changing the background image of perhaps 300 cells, and checking to see if it's time to refresh the page and issuing an AJAX request if so. That timer is running with a 1/10-sec interval and things are tight, for sure, but the code gets through all of those jobs, once in a while with one clock tick coming on top of the previous.
So I doubt you'll have any trouble with a 1-sec interval and just one tick handler.

Fooling the Internet Explorer Javascript engine into letting a script run

I'm repeatedly coming into troubles with Internet Explorer's "This script is taking too long to run, would you like to continue?" messages. I am wondering if anyone is aware of a clever way to trick the JS engine into keeping quiet? Based on some searching I did, I found that the engine monitors states it thinks potentially could be infinitely looping, so I thought maybe I could add some logic to change up the execution every once in a while to fool it into leaving it alone, but no luck. I also tried breaking up a longer loop into several shorter ones, but that hasn't helped. Specifically the code that is currently causing issues is the expansion of nodes in a tree structure. The code is looping over the current nodes and expanding each. It's a trivial thing to write in Javascript, but I can't allow these timeout errors, so I think my only option might be to request pre-expanded view data via AJAX. I'm currently working in a DEV environment with a small(ish) data set and I know this will not fly in other environments. Has anyone managed to suppress these warnings?
Using setTimeout
A good way is simulating threaded execution using setTimeout() function calls. This requires splitting your whole processing into smaller parts and queueing them one after another. Timeouts can be set quite close to each other but they will run one by one when each of them finishes execution.
How about spacing it using a series of events. So a loop occurs sends an event, listener to event triggers and does a loop. etc..?
Why not break your function into a series of steps and queue them up using jQuery?
http://api.jquery.com/queue/
Have you tried making it output something every once in a while? It might be that it just checks for output and if there hasn't been any in x seconds, it assumes you're in an infinite loop.
If outputting works, you could try something like adding and then immediately deleting something really small (like an empty <span>).
A very common solution for this problem is to use setTimeout function.
The way you do it is that you separate the process into smaller pieces a then execute those pieces one after another using the setTimeout function.
I think this http://www.julienlecomte.net/blog/2007/10/28/ should help you.
There is also another option introduced by HTML5 WebWorkers.
This new standard should allow you to execute long running tasks in a separate thread and then report any results in a callback.
You can read about it here robertnyman.com/2010/03/25/using-html5-web-workers-to-have-background-computational-power/
Unfortunatelly, it is not supported by IE according to html5demos.com/
I think the timeout is more based on the number of statements than timing or heuristics. You could go a long way to increasing the amount your code can handle before triggering the warning by optimizing your code for simple things -- especially if you are using helper APIs on another library like jQuery. For example, change this:
$.each(arr, function(value) {
// do stuff
});
to this:
for (var i = 0, l = arr.length; i < l; i++) {
var value = arr[i];
// do stuff
}
Another easy one -- cache access to fields. If you have two instances of "foo.bar", store the result in a variable and use it, wherever that makes sense.
Obviously I have no idea what your code looks like, but I bet you could do a lot to improve it as these little things really add up when you're talking about this timeout problem.
I managed to do this by using prototypes Function#defer method, which is essentially the same as using the setTimeout method. Thanks everyone!

Categories