Cocoa/Mac:JavaScript核心在第38次调用时崩溃

Cocoa/Mac:JavaScript核心在第38次调用时崩溃,javascript,xcode,macos,cocoa,javascriptcore,Javascript,Xcode,Macos,Cocoa,Javascriptcore,我们正在为MacOSX(10.8)开发一个Cocoa应用程序,它需要使用JavaScript库(说来话长,为什么我们必须使用JavaScript) 在一个演示应用程序中,一切似乎都很好,但是在我们的项目中合并代码时,我们可以调用函数37次而没有问题,然后第38次崩溃 为了调用JS代码,我们使用Apple的JSWrappers.m(来自JavaScriptCoreHeadStart示例)。 崩溃的线路(EXC#U坏访问)为#149: 如上所述,它在第38次崩溃时调用了-callStringJSFu

我们正在为MacOSX(10.8)开发一个Cocoa应用程序,它需要使用JavaScript库(说来话长,为什么我们必须使用JavaScript)

在一个演示应用程序中,一切似乎都很好,但是在我们的项目中合并代码时,我们可以调用函数37次而没有问题,然后第38次崩溃

为了调用JS代码,我们使用Apple的JSWrappers.m(来自JavaScriptCoreHeadStart示例)。 崩溃的线路(EXC#U坏访问)为#149:

如上所述,它在第38次崩溃时调用了
-callStringJSFunction:withParameters:
,无论输入是什么(它与任何输入字符串崩溃,如果在之前的37次迭代中使用相同的字符串,则该字符串可以工作)。 EXC_BAD_访问不是由输入变量引起的,因为访问它们(例如在该行之前调用
self.jsContext
)是有效的:导致崩溃的是函数调用本身

我们不知道是什么导致了这个问题,也不知道如何进行更多的调试。有人有什么暗示吗? 谢谢

//编辑

我必须纠正自己:它在“演示应用程序”上也不起作用。即使在这种情况下,我们第38次调用
-callStringJSFunction:withParameters:

//编辑2

如果每次调用函数时都重新创建JSWrappers对象(和一个新的JSGlobalContext),那么它就不会崩溃。然而,这使得代码的速度慢了很多(毫不奇怪,因为JS解释器每次都要读取脚本,而且这个脚本相当大)

//编辑3


另一个发现是:以32位构建应用程序会导致代码崩溃。相反,64位构建可以完美地工作:JS代码在我们希望的任何时候都可以执行,没有任何问题。这很奇怪:这可能是JavaScript核心框架本身的一个bug吗?

回答了我自己的问题

显然,这是JavaScript核心中的一个bug(?)。在32位二进制文件上,由于某些原因,调用函数的次数不能超过37次(内存问题?)。 这些问题不会出现在64位二进制文件上


这种行为发生在OSX 10.8.4上。

有点老掉牙,但今天有点相关。
我们仍然支持回到iOS 8.2,并发现许多iOS 8.4用户出现了这个问题。一些研究表明,这似乎是一个错误的iOS版本在这个时候

在综合测试中,我在多个线程上调用了相同的
-callWithArguments:@[]
函数(100计数循环中的新线程)——这将在大多数测试设备上完成,即使是运行iOS 9.x的32位iPod touch。共同点是iOS 8.x,甚至在iPhone5s上(64位,1GB内存),导致WTFCrash

在我们的生产应用程序中,该应用程序确实调用了
callWithArguments
async,有时还会在多个线程上同时调用。似乎多个线程同时调用了一个长时间运行的函数并导致了问题。为了停止这种情况,我将
callWithArguments
包装在一个

 @synchronized (<#token#>) {
        <#statements#>
    }
@synchronized(){
}
这似乎解决了这个问题,并阻止了所有测试iOS版本(8.4、9.x、10.3)以及多个体系结构上的崩溃。由于这些调用是在后台线程上进行的,因此对UI没有影响

虽然这可能不是最优雅的方法/解决方案,但它似乎解决了我们的问题,即每天有数十名用户间歇性崩溃。话虽如此,如果有人知道更好的方法,请告诉我

tl;dr

调用同一函数的多个线程导致该函数在
WTFCrash
中爆炸。在
@synchronized
锁中封装调用似乎可以修复它。

我遇到了类似的问题。你有我可以复制的雷达吗?@Simon对不起,我没有。然而,我很确定这是JavaScript核心的一个bug,可能与内存有关(我的JS库相当大)。
 @synchronized (<#token#>) {
        <#statements#>
    }