调用 JS_NewStringCopyN 两次时的 SIGSEGV
SIGSEGV when calling JS_NewStringCopyN twice
我一直在尝试使用 Ubuntu 16.04.3 LTS mozjs185-1.0
附带的 Mozilla / SeaMonkey JavaScript 库,但遇到 SIGSEGV
时我尝试调用 JS_NewStringCopyN
两次以从 char *
字符串中分配两个 JSString
对象。
我的示例代码如下:
#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
) 并且在某处它正在尝试进行标记和清除传递,但正在访问一些无效的内存,调用 js::gc::ArenaBitmap::markIfUnmarked
.
在回溯跟踪中深入 30 级
我的理论是,在调用第一个 JS_NewStringCopyN
后,我忘了做一些未记录的事情。任何建议或帮助将不胜感激。
在上面的示例代码中,我发现的问题是 JSCompartment
在使用前必须手动初始化。
因此,通过添加:
compartment.init();
在 JSCompartment compartment(rt);
中构造隔间后,两个 JS_NewStringCopyN
被调用而没有错误,垃圾收集器 JS_gc
运行也没有错误。为什么 JSCompartment
不在其构造函数中调用 JSCompartment::init()
以及为什么没有明确记录这超出了我的范围。
我一直在尝试使用 Ubuntu 16.04.3 LTS mozjs185-1.0
附带的 Mozilla / SeaMonkey JavaScript 库,但遇到 SIGSEGV
时我尝试调用 JS_NewStringCopyN
两次以从 char *
字符串中分配两个 JSString
对象。
我的示例代码如下:
#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
) 并且在某处它正在尝试进行标记和清除传递,但正在访问一些无效的内存,调用 js::gc::ArenaBitmap::markIfUnmarked
.
我的理论是,在调用第一个 JS_NewStringCopyN
后,我忘了做一些未记录的事情。任何建议或帮助将不胜感激。
在上面的示例代码中,我发现的问题是 JSCompartment
在使用前必须手动初始化。
因此,通过添加:
compartment.init();
在 JSCompartment compartment(rt);
中构造隔间后,两个 JS_NewStringCopyN
被调用而没有错误,垃圾收集器 JS_gc
运行也没有错误。为什么 JSCompartment
不在其构造函数中调用 JSCompartment::init()
以及为什么没有明确记录这超出了我的范围。