【问题标题】:SIGSEGV when calling JS_NewStringCopyN twice两次调用 JS_NewStringCopyN 时的 SIGSEGV
【发布时间】:2017-09-07 04:05:26
【问题描述】:

我一直在尝试使用 Ubuntu 16.04.3 LTS 附带的 Mozilla / SeaMonkey JavaScript 库 mozjs185-1.0,但是当我尝试调用 JS_NewStringCopyN 两次以分配两个 JSString 时遇到了 SIGSEGV来自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) 并且它试图在某处进行标记和通过调用js::gc::ArenaBitmap::markIfUnmarked,扫描通过,但正在访问一些无效内存,在回溯中深入 30 层。

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

【问题讨论】:

  • 作为记录,虽然我在下面有一个解决问题的方法,但我需要解决的问题在 JavaScript 中的内存池损坏方面有点微妙,与提交的数据结构有关没有适当的终止元素,会导致 JavaScript 内存损坏和垃圾收集器崩溃。

标签: c++ javascript-objects seamonkey


【解决方案1】:

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

因此,通过添加:

compartment.init();

JSCompartment compartment(rt); 中的隔间构造之后,两个JS_NewStringCopyN 被正确调用,垃圾收集器JS_gc 正常运行。为什么 JSCompartment 不在其构造函数中调用 JSCompartment::init() 以及为什么没有明确记录在案,这超出了我的理解。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-19
    • 1970-01-01
    • 2014-10-21
    • 2017-02-16
    相关资源
    最近更新 更多