Everything relevant on the internet I've read indicates that Javascript is single-threaded (aside from Web Workers, which run in a different global context and shouldn't be able to directly affect the state in the main thread). However, while debugging some code, I noticed that even while I was paused on such-and-such a line, variables kept changing, even when I didn't step over lines of code. Investigating further, I noticed that, again, even while paused in the debugger (and I wasn't touching anything), logs were logged and errors were thrown every second according to a timeout that had been set.
I am using OS: Windows 10 Enterprise, version 1803, OS build 17134.407.
I experienced the issue in Firefox 63.0.1 (64-bit).
When I tried it in Chrome 70.0.3538.102 (Official Build) (64-bit), however, the issue did not occur - pausing in the debugger appeared to pause all computation, as expected.
I can't provide any useful code, because 1. it's company code, and 2. it's a multithreading style problem, which makes it very difficult to narrow down to any given section of code. Things that might be relevant, aside from aforementioned browser differences: it's an AngularJS application, served to the browser from NodeJS. We're using $interval(), timeout(), $http, and Stomp websocket connections.
According to my understanding, this apparently multithreaded behavior should be impossible. How could this happen?
Nodejs in fact is not single threaded. It has basically two parts:
Javascript part. Basically Event loop processes (single threaded).
C++ part (libuv library), thanks to V8. This part implements a thread pool with multiple thread to compute costly operations. This way we don't block the event loop.
So, maybe you can check all the modules that you are using and check their implementation. Anyone implemented in C++ uses the thread pool on the background.
Related
Firefox allows to attach to web workers. You can go to about:debugging, see the list of active workers, and click on "debug" to attach.
But what to do if the application creates a short-lived worker? I want to set a breakpoint, but I cannot do so in advance before the worker is created. (At least, I have not found a way to do so. For instance, setting a breakpoint with the debugger statement does not work in Firefox 54.)
As a very crude workaround, I can delay the startup of the web worker by using setTimeout, so I can use the time to open about:debugging and attach to the new worker. This is not a good solution, however.
Is there an efficient way to set a breakpoint in advance (before the worker is even started)?
I've forked a very simple webworker jsfiddle, and debugger; works in the chrome debug tools, but not in firefox debug tools : https://jsfiddle.net/ckprrLxz/2/
Currently, it is not possible. At least not in Firefox 54.
As a workaround, I would recommend to modify the code so that web workers are reused, at least during debugging. In my specific use case, it was relatively easy to do so. Depending on the situation, it might be more difficult or not even possible. In that case, you have to use other techniques to debug the code. For instance, by writing tests for the web worker code (which might be a good idea, anyway).
Delaying sending the message to the newly created web worker with setTimeout is theoretically also an option, as it gives you some time to attach the debugger. It is certainly not ideal, but it can be used as a last resort.
I have been working with teaching kids programming in Javascript using a combination of online and self made environment.
At some stage most of the kids encounter a time when they create an infinite loop. In days gone by. an infinite loop was expected to be a child's first program with
10 PRINT "Mike is cool"
20 GOTO 10
Writing something like that in JavaScript is problematic
while(true) {
print("Mike is cool");
}
Doesn't work because of the synchronous nature of JavaScript, and that's something that they will have to learn. The problem isn't that their program doesn't work as expected, but when they run their program the entire world stops!
Some Browsers have enough control remaining to close the window, some just Lock. If you are using an in-browser environment (like jsfiddle, jsbin etc) you don't have enough control to stop the rogue "task"
You can't audit the code beforehand (It literally is the halting problem), but is there any reasonable way of mitigating the symptoms?
The programming environment on Khan Academy seems to achieve this
http://www.khanacademy.org/cs/breaking/4804951998988288
What is it doing to handle the excessive run-time? How is it managing to do this while the while is still running?
You could accomplish this in a browser by using a web worker, which does not lock the UI thread of the web browser because the browser runs a separate thread for the web worker. Your looping code for the example would be run in the web worker.
Web worker threads are an HTML5 feature so this approach will not work on older browsers. You can set breakpoints and debug web workers, at least in Chrome and Safari. You can learn the basics of web worker threads at:
http://www.html5rocks.com/en/tutorials/workers/basics/
I have a single process node.js application, which I wish to debug with Intellij IDEA 11 32 bits (node.js is 32 bits too).
So, I place an initial breakpoint and run. The debugger stops at the breakpoint, but then it refuses to do any of the following:
step into
go to another breakpoint
pause execution
When I step into, it seems just to run, without stepping through the code. Once running, it ignores any subsequent breakpoints and does not break when I press the pause button.
This issue drives me crazy.
Any ideas on how should I troubleshoot it?
EDIT
More info. After IDEA breaks on the first breakpoint (the only successful time) I try to inspect the variables and am unable to see any. IDEA is stuck on "Collecting data..." The watch window does not work too.
EDIT2
Justed posted an issue to their bug tracking system - http://youtrack.jetbrains.com/issue/IDEA-112925
I've been noticing that IntelliJ's node.js debugger kinda sucks. It's death by 1000 cuts. I love IntelliJ to death, its such a nice IDE. But for node, the debugger has a million different scenarios where breakpoints don't work properly, and another million where it doesn't properly give you access to the in-scope variable values, and another million where it doesn't step properly...
I'm gonna hafta try looking for another tool..
UPDATE 2014-01-13: I've been using IntelliJ's debugger for a while now (having found no other good tool). It seems some of the problems with it are problems with node or v8 itself. Most of the problems I was having have either actually been solved by newer versions of IntelliJ, or by using this workaround:
1. create a file called proxyDebug.js
2. put the following content in it:
require('path/to/the/script/you/want/to/debug.js')
3. point your debugger to that file
Apparently the node.js debugging hooks go buggy at the entrypoint script, so by creating this proxy entrypoint that we don't care at all about, there won't be any weird bugs caused by that in the scripts you do care about. The bugs this workaround fixed were missed breakpoints, predefined variables (exports, module, process, etc) being inaccessible by the debugger, and one or two other things I can't remember.
Last WebStorm version I tried (7.0.3) actually takes ages in collecting data but eventually works. If it seems stuck to you, try to leave it for a minute
We are developing a Cocoa app for Mac OSX (10.8) which needs to use a JavaScript library (long story why we must use JavaScript).
In a demo application everything seemed to be just fine, but while incorporating the code in our project, we can call the function 37 times without issues and then crashes the 38th time.
To call the JS code we are using Apple's JSWrappers.m (from the JavaScriptCoreHeadStart example).
The line that crashes (with a EXC_BAD_ACCESS) is #149:
JSObjectCallAsFunction(self.jsContext, jsFunction, NULL, argumentCount, arguments, NULL);
As stated above, it crashes on the 38th time -callStringJSFunction:withParameters: is called, no matter what the input is (it crashes with any input string, and the same string works if used in the 37 previous iterations).
The EXC_BAD_ACCESS is not caused by an input variable, as accessing them (such as calling self.jsContext just immediately before that line) works: it is the function call itself that causes the crash.
We have no idea on what it may be causing this issue, and no idea on how to debug more. Does anyone have any hint?
Thanks.
//EDIT
I must correct myself: it doesn't work on the "demo app" too. Even in that case, the code crashes the 38th time we call -callStringJSFunction:withParameters:
//EDIT2
If we re-create the JSWrappers object (and a new JSGlobalContext) every time the function is called, it does not crash anymore. However, this makes the code a lot slower (not surprisingly, as the JS interpreter has to read the script every time - and it's a rather big one).
//EDIT3
Another discovery: building the app in 32 bit makes the code crash. Building in 64 bit, instead, works flawlessly: the JS code is executed without issues any time we wish. This is strange: could this possibly be a bug in the JavaScript Core framework itself?
Answering my own question.
Apparently it is a bug (?) in JavaScript Core. On 32-bit binaries, for some reasons we cannot call the function more than 37 times (memory issues?).
Those issues do not appear on 64-bit binaries.
This behavior happens on OSX 10.8.4.
A bit of an old thread, but somewhat relevant today.
We are still supporting back to iOS 8.2 and found that this issue was cropping up with a number of iOS 8.4 users. Some research shows that is appears to be a bug with iOS versions around this time.
Under synthetic testing, I was calling the same -callWithArguments:#[] function on multiple threads (a new thread in a 100 count for-loop) - this would complete on most test devices, even the 32bit iPod touch, running iOS 9.x. The common denominator was iOS 8.x, even on the iPhone 5S (64bit, 1GB RAM), causing a WTFCrash.
In our production app, the app does call the callWithArguments async and, on occasion, simultaneously on multiple threads. It appears that multiple threads were calling a long-running function at the same time and causing issues. To then stop this, I wrapped the callWithArguments in an
#synchronized (<#token#>) {
<#statements#>
}
This seemed to handle this and stopped crashes on all tested iOS versions (8.4, 9.x, 10.3) along with multiple architectures. As these calls were being made on background threads, this had no impact on the UI.
Although this might not be the most graceful approach/ resolution, it seems to have resolved our issue where dozens of users were getting intermittent crashes every day. Having said that, if anyone knows a better way of doing this, please let me know.
tl;dr
Multiple threads calling the same function caused it to bomb out with WTFCrash. Wrapping the call in a #synchronized lock seemed to fix it.
The project I'm working on involves a "planning" screen, which is entirely made with backbone.js (the other pages of the app are not).
My issue is that from times to times, chrome freezes and the web view stop responding to any interaction. Sometimes, I can manage to quit chrome itself, but usually the controls does not answer either.
I'm pretty convinced this is related to the js code. It seems to me that when a script takes too much time, or loops indefinitely, Chrome can detect this and interrupt the script. However, since this is not the case, I'm thinking that too many js objects stay in memory.
Whatever the cause is, I would like to know which chrome dev tools can help me here. While I'm not a beginner in js, asides setting breakpoints and calling console.log, I have no idea how to debug JS apps. I'm not opposed to use another browser if the dev tools are more suited.
Thanks a lot for your time !
FTR : This is a rails 3.2.8 app, using mongodb, & Backbone.js 0.9.2. The js code is written in coffeescript. This issue happened on my macbook air 2012 running mountain lion, as well as on the client machine which runs on windows 7. The issue appeared at least on chrome 22 & 23.
Using the Javascript CPU profiler, I was able to find the group of functions that seems to be responsible for the freezing.
I'm still open to any advice/ressource on debugging javascript code.
Make a console.log in the loop and check if its the same point freezing on all chrome versions. There is a limit see Browser Javascript Stack size limit.
Maybe add some code? Because there could be some memory leaks especially with event handlers!
What I would do is the long and weary approach to getting your hands dirty with console.log. --- in this case.
In your case, and THX for the hint by the way (finding the offender with the CPU profiler, I'll try that next time round), I guess the offenders might be some functions "callbacking" themselves .. probably via some sort of event-handling/bubbling/callback-combination.
What happens then usually is that it just doesn't recognize the endless-loop, because the callback-stack is kinda "broken". Therefor it will never throw a browser-error.
If you have any luck, it doesn't kill the browser quick enough to kill the console. I did have that at times, the console killed (remaining silent), the coffeescript files not even loaded in the debugger (I use a JIT-coffee-to-js-translator as in JS-MVC) ... the page frozen or not doing anything ...
So, if indeed you are lucky and the debugger spits out your console.logs you can thereby guess where your unwanted loop is hiding. Just by looking at the repeated order of the output statements.
of course you know you can set breakpoints right? even conditional breakpoints
I'm currently struggling a bit untangling a similar sounding loop - i guess in case of emergency some alert() calls in your code would at least slow the loop down
or maybe some wait calls (bad idea)
my loop is running so fast I loose my console log!