2013-07-29 1 views
2

Мы разрабатываем приложение Cocoa для Mac OSX (10.8), которое должно использовать библиотеку JavaScript (длинная история, почему мы должны использовать JavaScript).Cocoa/Mac: JavaScript Core crash на 38-й вызов

В демонстрационном приложении все, казалось, было прекрасным, но при включении кода в наш проект мы можем вызывать функцию 37 раз без проблем, а затем сбой 38-го раза.

Для вызова кода JS мы используем JSWrappers.ms от Apple (из примера JavaScriptCoreHeadStart). Линия, которая выходит из строя (с EXC_BAD_ACCESS) является # 149:

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

Как было сказано выше, он падает на 38-й раз -callStringJSFunction:withParameters: не называется, независимо от того, что вход (он выходит из строя любой входной строки, и эта же строка работает, если используется в предыдущих предыдущих итерациях). EXC_BAD_ACCESS не вызван входной переменной, поскольку доступ к ним (например, вызов self.jsContext непосредственно перед этой строкой) работает: это сам вызов функции вызывает сбои.

Мы понятия не имеем, что это может вызвать эту проблему, и не знаю, как отлаживать больше. У кого-нибудь есть намек? Спасибо.

// EDIT

я должен исправить себя: он не работает на «демо-приложение» тоже. Даже в этом случае код аварий 38-й раз, когда мы называем -callStringJSFunction:withParameters:

// EDIT2

Если мы заново создать объект в JSWrappers (и новый JSGlobalContext) каждый раз, когда вызывается функция, она не откажет больше. Однако это делает код намного медленнее (неудивительно, так как интерпретатор JS должен каждый раз читать скрипт - и он довольно большой).

// EDIT3

Еще одно открытие: создание приложения в 32 бита делает сбой кода. Вместо этого в 64-битном исполнении работает безупречно: код JS выполняется без проблем в любое время. Это странно: может ли это быть ошибкой в ​​самой структуре JavaScript Core?

ответ

1

Отвечая на мой вопрос.

Видимо, это ошибка (?) В JavaScript Core. В 32-битных двоичных файлах по некоторым причинам мы не можем вызывать функцию более 37 раз (проблемы с памятью?). Эти проблемы не отображаются в 64-битных двоичных файлах.

Такое поведение наблюдается в OSX 10.8.4.

+0

Я сталкиваюсь с чем-то похожим. У вас есть радар, который я могу дублировать? – Simon

+0

@ Симон Извините, не знаю. Тем не менее, я уверен, что это ошибка с JavaScript Core, вероятно, связанная с памятью (моя библиотека JS была довольно большой). – Qualcuno

0

Немного о старой теме, но в некоторой степени актуально сегодня.
Мы по-прежнему поддерживаем поддержку iOS 8.2 и обнаружили, что эта проблема возникает с несколькими пользователями iOS 8.4. Некоторые исследования показывают, что в настоящее время это ошибка в версиях iOS.

При синтетическом тестировании я вызывал одну и ту же функцию -callWithArguments:@[] на несколько потоков (новый поток в 100 count for-loop) - это будет завершено на большинстве тестовых устройств, даже 32-битных iPod touch, работающих под управлением iOS 9.x , Общим знаменателем был iOS 8.x, даже на iPhone 5S (64 бит, 1 ГБ ОЗУ), вызывая WTFCrash.

В нашем производственном приложении приложение вызывает асинхронное подключение callWithArguments и, одновременно, на несколько потоков. Похоже, что несколько потоков одновременно вызывали долговременную функцию и вызывают проблемы. Для того, чтобы потом остановить это, я завернул callWithArguments в

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

Это, казалось, справиться с этим и остановил сбои на все протестированные версии IOS (8,4, 9.x, 10.3) вместе с несколькими архитектурами. Поскольку эти вызовы выполнялись по фоновым потокам, это не влияло на пользовательский интерфейс.

Хотя это может быть не самый изящный подход/разрешение, похоже, он разрешил нашу проблему, когда десятки пользователей ежедневно сталкивались с прерывистыми сбоями. Сказав это, если кто-нибудь знает лучший способ сделать это, пожалуйста, дайте мне знать.

Т.Л., др
Несколько потоков называя ту же функцию, приводивших разбомбить с WTFCrash. Завершение вызова в замке @synchronized, казалось, исправить.