Cocoa/Mac: JavaScript Core crash on the 38th call - javascript

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.

Related

Javascript function execution time increases 10x after some time

I have somewhat expensive task that needs to be executed a few times by my users. The task uses the ImageTracer library. This task starts off taking about 1 second, but usually after executing a few times (2-10) the task suddenly takes 20+ seconds, even though none of the input arguments are different. Sometimes I never hit this increase, and sometimes it takes much longer to hit.
Other libraries I am using:
Vue.js
Fabric.js
My first guess was that this is some sort of memory issue, so I went to chrome dev tools and captured the heap size. You can download the profile here and here is a screenshot:
You can clearly see that the last 2 task executions took significantly longer than the first couple. I am not very experienced with js and the chrome dev tools, but that doesn't seem like a memory leak to me. The heap size is not significantly larger at the end than at the beginning (both around 8mb). Please correct me if I am wrong and this does indicate a memory leak.
However those memory spikes seem like they might be an issue (or maybe a symptom of some other issue). Zooming in you can see an immediate jump from 15mb to 80mb and then back down to 15mb only 20ms later. Strangly the jump seems to coincide with a Major GC.
I am not sure if this is a problem and if it is how to further debug it.
I tried whittling the code down to a small self contained reproducible example, but as I got the code smaller and smaller the error became more and more rare to trigger, eventually disappearing. To me this also indicated I am dealing with some sort of memory issue.
I have made a somewhat simplified version that does show my issue however.
For me this problem is only reproducible in Chrome (also tested in Safari and Firefox). I am using a 2018 MacBook Pro with 16GB of memory and running Catalina.
My Questions:
Can anyone see an obvious issue in the profile posted above?
Is this most likely a memory bug and if so what are the next steps to continue debugging?
Are there any workarounds that would enable me to essentially reload or reset the offending js library (since the first couple of task executions always seem to go smoothly.

Javascript acting multitheaded in Firefox

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.

Chrome Bug 805525 in Android v62 and above crashing on css transforms and animations - is there a workaround?

Update 2018-03-01:
This issue has apparently been fixed in version 66. Tested a number of pages in Android Chrome Dev and Canary, no crashes observed even during long and/or heavy runs. I never did find a workaround, however 66 should be hitting Chrome Beta soon, and not too long after Stable so normal users should be able to run them again on Android in the regular version of Chrome within a few(ish) weeks. Incidentally, this is the same update that Chrome will fully discontinue trust in Symantec-CA-based HTTPS/SSL certs. I have noticed it seems slightly janky in comparison to before, but will have to test as this could be merely subjective on my part, or due to changes in my code looking for workarounds. Further info can be found in the Chromium Bug report linked to below.
** Note: If you've followed this post... I have to admit I thought I had a workaround by rounding values to only two decimals out. However, I later realized this was causing a side-effect (because of an optimization I had made) of scale3d-ing some elements to 0,0,0, essentially causing them not to be rendered, and thus not triggering the problem for a long time. When I temporarily removed scaling, said elements rendered again, and the bug was triggered. Deep andhumble appologies, but-- problem not solved. So, I have removed my answer. Here are some things I have tried, none of which were successful:
Rounding transform decimal values to x.xx, two digits out.
Rounding transform values to straight integers.
Using setInterval instead of RAF to see if that was a factor (ugh!).
Using a style tag and .innerHTML to set dynamic transforms via css instead of the DOM (this was surprisingly efficient, but still triggered a crash just the same.
I've tried narrowing it down to particular transform parameters, numerical patterns, element nesting depths, just about anything I can think of to get around triggering a crash, and it looks like there is only one pattern: every time you do a transform there is a chance of a crash. It's a seemingly tiny probability, but doing scripted animations, even if you optimize to prevent repeats of identical transforms, makes the crash inevitable. I can make it take longer, but I can't prevent it.
Now, I've seen similar reports all over the web regarding recent problems with CSS in Chrome since November, when version 62 update was pushed on the stable channel. This last test, using a dynamically generates, embedded style-sheet to update the transforms was especially dis-heartening. There doesn't seem to be a way around it except to wait for version 67 when chromium.org says the fix should come out. That is months away for the typical Android-user.
This problem is not relegated to scripted animations either. I've seen similar issues reported with CSS animations and transitions as well.
I've gone to the extent of trying a number of my animation engines from the past, all of which work beautifully on version 61 down to when RAF was available. I've even written new, simple test engines, just for this. I've tried a number of other developers engines. Still crashes.
At this point, I think the only thing that can be done is to wait for the fix, and possibly get enough attention from enough people to hope they will up the priority.
They said in the ticket it's a problem with a code-optimization. I would really like to see them revert that portion back in version 65 before it hits the stable channel, so the average user will not see this problem soon. There's still time to generate another build and get it out before then.
Anyone who would like to see this happen, please go to the link below and put your two cents in on the ticket at chromium.org.
PREVIOUS UPDATE: This issue has now been tested and confirmed at chromium.org as a bug in the GPU rasterization code, affecting up to version 66 of Chrome for Android, and appearing after build 62.0.3197.0 (the last build unaffected). Their engineers are now working to fix it.
I am leaving this open for anyone who has run into this issue, so they don't think it's a problem with their code, and in case anyone happens to read it that can either contribute to the fix or offer a reasonable workaround until a patched build is released. If anyone does find a workaround, please provide it as an answer here.
For those interested, the link to the ticket is below. Here is an excerpt from the bug report:
Tested the issue in Android and able to reproduce the issue.
Steps Followed:
1. Launched the Chrome Browser.
2. Navigate to the URL: https://keithclark.co.uk/labs/css-fps/
3. Tap on any of the tab and try to access the game
4. Observed that Chrome gets hanged.
Chrome versions tested:
64.0.3282.116 Stable/Beta, 65.0.3325.16 (dev) 66.0.3328.0(Canary)
OS: Android 8.1.0
Android Devices: Pixel
Using the per-revision bisect providing the bisect results, Good Build
- 62.0.3197.0 (497604) Bad Build - 62.0.3198.0 (497674)
You are looking for a change made after 497614(GOOD), but before
497615(BAD).
Previously:
Not quite sure if this is a Javascript, CSS, or Android problem-- but here goes...
Basic Question: What do I need to do to keep my pages with scripted RAF 3D transforms from locking up Chrome vs. 62 and above on Android? Is anyone else having this problem?
**Note: This problem may actually be a Chromium issue. I have opened a bug report with Chromium Project. Those interested can view the ticket here: https://bugs.chromium.org/p/chromium/issues/detail?id=805525
I am leaving this open for now so they can view the full description, and in case it turns out I can fix my own pages with a change to my code. But please, read on... ;)
Background:
My pages work great on 61 and below. I manually updated Chrome on my Samsung Note 3 to version 63 stable recently, and found every page (not just mine) with complex, nested 3D transforms running on a requestAnimationFrame loop would lock up the browser. A perfect example is a page from Keith Clark, who has a CSS/HTML/Javascript proof-of-concept demo of a First-Person Shooter. Now, the mobile version worked great on my phone before. After the update, it locks up. My pages work really good, even on weak devices, till this update.
I've narrowed it down a bit. If I clear cache, and uninstall updates, the stock Chrome (41) runs these things great. Install updates to 63, 62, 64(beta), same problem. I can't remember if I tested 60 or 61, but update to version 59 and we're still golden. Firefox is fine. Opera is well, Opera. Same updates on desktop run great.
What I'm not totally sure of is if it's a problem with my phone. No other problems, ever. I know it's a little old, but it still blows most mobile devices off the shelf. Android version 5, Lollipop. Rooted. If any of that matters. Malware scans have always produced 0 with any AV/M app I've tried. I'm very careful.
Anyway, if anyone else has had this problem, or knows of it...
What do I need to change in my code to make it compatible with current Chrome on Android? Is this a problem I need to solve with code? I've looked everywhere but can't seem to find info specifically on it. All I can say is it's breaking my animations. I can't even use dev tools to figure it out, as running a perf check from my computer crashes my phone so bad Chrome dies and loses the connection and any performance data gained, taking my phones wallpaper along with it!
I'm not picking up any errors from my script-- it's fairly basic. I stripped it down to bare bones because I thought I had a runtime error, but nothing. Is there a change with the way Chrome for Android interprets the CSS or does the layering or something?
Sincere apologies if this ends up being off-topic, as I'm not totally sure if this a coding issue, or just a problem with my phone in particular. If it's a coding issue, that's what I need to know-- and how to fix it.

Why do I fail to debug a nodejs app in Intellij IDEA 11?

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

Chrome freezes on my backbone page: how to debug?

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!

Categories

Resources