【问题标题】:Cocoa/Mac: JavaScript Core crash on the 38th callCocoa/Mac:JavaScript Core 在第 38 次调用时崩溃
【发布时间】:2013-07-29 10:27:37
【问题描述】:

我们正在为 Mac OSX (10.8) 开发一个需要使用 JavaScript 库的 Cocoa 应用程序(为什么我们必须使用 JavaScript 很长的故事)。

在演示应用程序中,一切似乎都很好,但是在将代码合并到我们的项目中时,我们可以毫无问题地调用该函数 37 次,然后第 38 次崩溃。

要调用 JS 代码,我们使用 Apple 的 JSWrappers.m(来自 JavaScriptCoreHeadStart 示例)。 崩溃的行(带有 EXC_BAD_ACCESS)是 #149:

JSObjectCallAsFunction(self.jsContext, jsFunction, NULL, argumentCount, arguments, NULL);

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

我们不知道是什么原因导致了这个问题,也不知道如何调试更多。有没有人有任何提示? 谢谢。

//编辑

我必须纠正自己:它也不适用于“演示应用”。即使在这种情况下,代码在我们第 38 次调用 -callStringJSFunction:withParameters: 时也会崩溃

//EDIT2

如果我们在每次调用该函数时重新创建 JSWrappers 对象(和一个新的 JSGlobalContext),它就不会再崩溃了。然而,这使得代码变慢了很多(不足为奇,因为 JS 解释器每次都必须读取脚本 - 而且这是一个相当大的脚本)。

//EDIT3

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

【问题讨论】:

    标签: javascript xcode macos cocoa javascriptcore


    【解决方案1】:

    回答我自己的问题。

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

    此行为发生在 OSX 10.8.4 上。

    【讨论】:

    • 我遇到了类似的事情。你有我可以复制的雷达吗?
    • @Simon 对不起,我没有。但是,我很确定这是 JavaScript Core 的错误,可能与内存有关(我的 JS 库非常大)。
    【解决方案2】:

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

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

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

     @synchronized (<#token#>) {
            <#statements#>
        }
    

    这似乎解决了这个问题,并阻止了所有经过测试的 iOS 版本(8.4、9.x、10.3)以及多种架构的崩溃。由于这些调用是在后台线程上进行的,因此对 UI 没有影响。

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

    tl;dr
    多个线程调用相同的函数导致它被WTFCrash 炸毁。将调用封装在 @synchronized 锁中似乎可以解决问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-17
      • 1970-01-01
      • 1970-01-01
      • 2018-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-21
      相关资源
      最近更新 更多