两次调用JS_NewStringCopyN时的SIGSEGV

时间:2017-09-07 04:05:27

标签: c++ javascript-objects seamonkey

我一直在尝试使用Ubuntu 16.04.3 LTS附带的Mozilla / SeaMonkey JavaScript库mozjs185-1.0,但在尝试两次调用SIGSEGV时遇到JS_NewStringCopyNJSString字符串中分配两个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并崩溃。调试了1.8.5版本的Mozilla JavaScript库之后,我知道在第二次调用JS_NewStringCopyN期间发生的事情是垃圾收集器被调用(JS_gc)并且在某处它正在尝试做一个标记和扫描通过,但是通过调用js::gc::ArenaBitmap::markIfUnmarked访问一些无效的内存,在后面跟踪中有30个深度。

我的理论是,在调用第一个JS_NewStringCopyN后,我忘记了一些无记录的事情。任何建议或帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

在上面的示例代码中,我发现的问题是必须在使用前手动初始化JSCompartment

因此,通过添加:

compartment.init();

JSCompartment compartment(rt);中构建隔离专区之后,两个JS_NewStringCopyN被调用而没有错误,垃圾收集器JS_gc运行时没有错误。为什么JSCompartment在其构造函数中没有调用JSCompartment::init()以及为什么没有明确记录这些内容超出了我的范围。