Я пытался использовать библиотеку JavaScript Mozilla / SeaMonkey, которая поставляется с Ubuntu 16.04.3 LTS, mozjs185-1.0
, но встречаюсь с SIGSEGV
когда я пытаюсь позвонить JS_NewStringCopyN
дважды выделить два JSString
объекты из char *
строки.
Мой пример кода выглядит следующим образом:
#include <js/jsapi.h>
#include <js/jscntxt.h>
#include <js/jscompartment.h>
size_t gStackChunkSize = 8192;
static void
my_ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)
{ }
int main(int argc, char *argv[]) {
JSRuntime *rt = JS_NewRuntime(256L * 1024L * 1024L);
if (!rt)
return -1;
JSCompartment compartment(rt);
JSContext *cx = JS_NewContext(rt, gStackChunkSize);
if (!cx)
return -2;
JS_SetErrorReporter(cx, my_ErrorReporter);
cx->compartment = &compartment;
const char data[] = "PScript5.dll Version 5.2.2";
const char data2[] = "Thom Parker";
JSString *str = JS_NewStringCopyN(cx, data, sizeof(data));
JSString *str2 = JS_NewStringCopyN(cx, data2, sizeof(data2));
return 0;
}
Который я собираю с:
g++ test.cpp -o mdntest -I/usr/include/nspr -lmozjs185-1.0 -L/usr/lib/x86_64-linux-gnu -lz -lnspr4 -lpthread
Когда я бегу ./mdntest
это генерирует SIGSEGV
и вылетает. Отладив версию библиотеки Mozilla JavaScript версии 1.8.5, я знаю, что происходит во время второго вызова JS_NewStringCopyN
что сборщик мусора называется (JS_gc
) и что где-то он пытается сделать отметку и проход развертки, но получает доступ к некоторой недействительной памяти, 30 уровней в глубине обратной трассировки с вызовом js::gc::ArenaBitmap::markIfUnmarked
,
Моя теория заключается в том, что есть кое-что недокументированное, что я забыл сделать после вызова первого JS_NewStringCopyN
, Любой совет или помощь будет принята с благодарностью.
В приведенном выше примере кода проблема, которую я обнаружил, заключается в том, что JSCompartment
должны быть инициализированы вручную перед использованием.
Таким образом, добавив:
compartment.init();
сразу после постройки купе в JSCompartment compartment(rt);
два JS_NewStringCopyN
вызываются без ошибок и сборщик мусора JS_gc
работает без ошибок. Почему JSCompartment
не звонит JSCompartment::init()
в его конструкторе, и почему это не ясно задокументировано, вне моего понимания.
Других решений пока нет …