Cocoa/Mac: JavaScript Core crash on the 38th call
Asked Answered
T

2

2

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?

Tenuis answered 29/7, 2013 at 10:27 Comment(0)
T
1

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.

Tenuis answered 29/7, 2013 at 14:25 Comment(2)
I'm running into something similar. Do you have a radar I can duplicate?Artistry
@Artistry I'm sorry, I don't. However, I'm pretty sure it's a bug with JavaScript Core, likely related with memory (my JS library was pretty big).Tenuis
S
0

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.

Sully answered 5/6, 2017 at 10:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.