2016-11-11 15 views
2

私はSpiderMonkeyを埋め込んだシンプルなC++プログラムを書いています。残念ながら、それはJS_NewContext()にあります。JSAPI segfault in JS_NewContext

jsapi_use.cppとして保存)プログラム:

#define __STDC_LIMIT_MACROS 
#include <js/Initialization.h> 
#include <jsapi.h> 
#include <stdint.h> 

static JSClass global_class = { 
#if 0 
    .name = "global", 
    .flags = JSCLASS_GLOBAL_FLAGS, 
    .addProperty = nullptr, 
    .delProperty = nullptr, 
    .getProperty = nullptr, 
    .setProperty = nullptr, 
    .enumerate = nullptr, 
    .resolve = nullptr, 
    .mayResolve = nullptr, 
    .finalize = nullptr, 
    .call = nullptr, 
    .hasInstance = nullptr, 
    .construct = nullptr, 
    .trace = JS_GlobalObjectTraceHook, 
#else 
    "global", JSCLASS_GLOBAL_FLAGS, 
    nullptr, nullptr, 
    nullptr, nullptr, 
    nullptr, nullptr, 
    nullptr, nullptr, 
    nullptr, nullptr, 
    nullptr, JS_GlobalObjectTraceHook, 
    {0}, 
#endif 
}; 

int main() { 
    if (!JS_Init()) 
    return 1; 
    JSRuntime *rt = 
     JS_NewRuntime(8L * 1024 * 1024 /*, JS::DefaultHeapMaxBytes, nullptr*/); 
    if (nullptr == rt) 
    return 1; 
    JSContext *cx = JS_NewContext(rt, 8192); 
    if (!cx) { 
    return 1; 
    } 
    { 
    JSAutoRequest ar(cx); 
    JS::RootedObject global(cx, JS_NewGlobalObject(cx, &global_class, nullptr, 
                JS::FireOnNewGlobalHook)); 

    if (!global) 
     return 1; 

    JS::RootedValue rval(cx); 
    { 
     JSAutoCompartment ac(cx, global); 
     JS_InitStandardClasses(cx, global); 

     const char *script = "'hello'+'world, it is '+new Date();"; 
     const char *filename = "noname"; 
     auto lineno = 1U; 
     JS::CompileOptions opts(cx); 
     opts.setFileAndLine(filename, lineno); 
     bool ok = JS::Evaluate(cx, opts, script, strlen(script), &rval); 
     if (!ok) 
     return 1; 
    } 
    if (rval.isString()) { 
     JSString *string = rval.toString(); 
     puts(JS_EncodeString(cx, string)); 
    } 
    } 
    JS_DestroyContext(cx); 
    JS_DestroyRuntime(rt); 
    JS_ShutDown(); 
    return 0; 
} 

それはJS_NewContextでクラッシュします。

私のMakefile: MAKEFLAGS:= -r -R

CXX := g++ 

CXXFLAGS += -g3 -std=gnu++14 

TARGET = $(subst ','\'',[email protected])#') 
SOURCE = $(subst ','\'',$<)#') 
PKG_CFLAGS=$(shell pkg-config --cflags mozjs-45) 
PKG_LDFLAGS=$(shell pkg-config --libs mozjs-45) 
%.o: %.cpp Makefile 
    $(CXX) $(CPPFLAGS) -c -o $(TARGET) $(CXXFLAGS) $(PKG_CFLAGS) $(SOURCE) 

%: %.o 
    $(CXX) -o $(TARGET) $(SOURCE) $(PKG_LDFLAGS) -lz -lpthread -ldl 

%.iii: %.cpp Makefile 
    cpp $(CPPFLAGS) -dD -CC -o $(TARGET) $(PKG_CFLAGS) $(SOURCE) 
    clang-format -i -- $(TARGET) 

Segmentation fault (core dumped). gdb`でmake jsapi_use; ./jsapi_use結果を実行するプログラムが原因NULLポインタを参照解除にSpiderMonkeyの奥深くセグメンテーションフォルトていることが明らかになりました。

私はFedora 24 Linuxのmozjs45からSpiderMonkeyを使用しています。

GDBバックトレース

Thread 1 "jsapi_use" received signal SIGSEGV, Segmentation fault. 
0x0000000000000000 in ??() 
#0 0x0000000000000000 in ??() 
#1 0x00007ffff7a6adb5 in js::ScriptBytecodeHasher::hash (l=<synthetic pointer>, l=<synthetic pointer>) at /usr/src/debug/firefox-45.4.0esr/js/src/jsscript.h:2412 
#2 js::detail::HashTable<js::SharedScriptData* const, js::HashSet<js::SharedScriptData*, js::ScriptBytecodeHasher, js::SystemAllocPolicy>::SetOps, js::SystemAllocPolicy>::prepareHash (l=<synthetic pointer>) at ../../dist/include/js/HashTable.h:1126 
#3 js::detail::HashTable<js::SharedScriptData* const, js::HashSet<js::SharedScriptData*, js::ScriptBytecodeHasher, js::SystemAllocPolicy>::SetOps, js::SystemAllocPolicy>::lookupForAdd (l=<synthetic pointer>, this=<optimized out>) at ../../dist/include/js/HashTable.h:1638 
#4 js::HashSet<js::SharedScriptData*, js::ScriptBytecodeHasher, js::SystemAllocPolicy>::lookupForAdd (l=<synthetic pointer>, this=<optimized out>) at ../../dist/include/js/HashTable.h:386 
#5 SaveSharedScriptData ([email protected]=0x639ed0, script=..., ssd=<optimized out>, nsrcnotes=1) at /usr/src/debug/firefox-45.4.0esr/js/src/jsscript.cpp:2502 
#6 0x00007ffff7a6b2f7 in JSScript::fullyInitTrivial ([email protected]=0x639ed0, script=..., [email protected]=...) at /usr/src/debug/firefox-45.4.0esr/js/src/jsscript.cpp:2886 
#7 0x00007ffff7a2a451 in CreateFunctionPrototype(JSContext *, enum JSProtoKey) (cx=0x639ed0, key=<optimized out>) at /usr/src/debug/firefox-45.4.0esr/js/src/jsfun.cpp:785 
#8 0x00007ffff7ae37b3 in js::GlobalObject::resolveConstructor (cx=0x639ed0, global=..., key=<optimized out>) at /usr/src/debug/firefox-45.4.0esr/js/src/vm/GlobalObject.cpp:158 
#9 0x00007ffff7ae3da7 in js::GlobalObject::ensureConstructor ([email protected]=0x639ed0, global=..., [email protected]=..., [email protected]=JSProto_Function) at /usr/src/debug/firefox-45.4.0esr/js/src/vm/GlobalObject.cpp:98 
#10 0x00007ffff79677ed in CreateObjectConstructor(JSContext *, enum JSProtoKey) (cx=0x639ed0, key=<optimized out>) at /usr/src/debug/firefox-45.4.0esr/js/src/builtin/Object.cpp:1035 
#11 0x00007ffff7ae382f in js::GlobalObject::resolveConstructor (cx=0x639ed0, global=..., key=<optimized out>) at /usr/src/debug/firefox-45.4.0esr/js/src/vm/GlobalObject.cpp:166 
#12 0x00007ffff772dda6 in CreateArrayPrototype(JSContext *, enum JSProtoKey) (cx=0x639ed0, key=<optimized out>) at /usr/src/debug/firefox-45.4.0esr/js/src/vm/GlobalObject.h:342 
#13 0x00007ffff7ae18ce in InitBareBuiltinCtor(JSContext *, JS::Handle<js::GlobalObject*>, enum JSProtoKey) ([email protected]=0x639ed0, global=..., [email protected]=..., [email protected]=JSProto_Array) at /usr/src/debug/firefox-45.4.0esr/js/src/vm/GlobalObject.cpp:368 
#14 0x00007ffff7ae1b08 in js::GlobalObject::initSelfHostingBuiltins ([email protected]=0x639ed0, [email protected]=..., [email protected]=0x7ffff7dbefa0 <intrinsic_functions>) at /usr/src/debug/firefox-45.4.0esr/js/src/vm/GlobalObject.cpp:413 
#15 0x00007ffff7b5041f in JSRuntime::createSelfHostingGlobal ([email protected]=0x639ed0) at /usr/src/debug/firefox-45.4.0esr/js/src/vm/SelfHosting.cpp:1730 
#16 0x00007ffff7b5056f in JSRuntime::initSelfHosting (this=0x617850, cx=0x639ed0) at /usr/src/debug/firefox-45.4.0esr/js/src/vm/SelfHosting.cpp:1754 
#17 0x00007ffff79e2103 in js::NewContext ([email protected]=0x617850, [email protected]=8192) at /usr/src/debug/firefox-45.4.0esr/js/src/jscntxt.cpp:122 
#18 0x00007ffff79e21ba in JS_NewContext ([email protected]=0x617850, [email protected]=8192) at /usr/src/debug/firefox-45.4.0esr/js/src/jsapi.cpp:566 
#19 0x0000000000400e4f in main() at jsapi_use.cpp:41 
+0

gdbから得たバックトレースの残りは何ですか? – ptomato

+0

@ptomato see編集 – Demi

答えて

2

問題はSpiderMonkeyのライブラリ内の未定義のシンボルによって引き起こされます。すなわち、HashBytes()関数はlibmozjs-45.soに定義されていません。この関数は、デバッグバックトレースに表示されるjs :: ScriptBytecodeHasher :: hash()関数によって呼び出されます。

ライブラリシンボルをリストすると、HashBytesが「弱く定義されている」ことがわかります。

$nm -gC libmozjs-45.so | grep HashBytes 
    w mozilla::HashBytes(void const*, unsigned long) 

"w"シンボルは、弱いシンボルとして特別にタグ付けされていない弱いシンボルです。

この問題を解決するにはmfbtライブラリをlibmozjs-45.soにリンクする必要があります。 js/src/moz.buildファイルを変更し、Spidermonkeyを再構築することで可能です。 moz.build

あなたが買ってあげる

if CONFIG['JS_STANDALONE']: 
    DEFINES['IMPL_MFBT'] = True 
    USE_LIBS += [ 
     'mfbt', 
    ] 
else: 

if not CONFIG['JS_STANDALONE']: 

を置き換える:

if CONFIG['JS_STANDALONE']: 
    DEFINES['IMPL_MFBT'] = True 
    USE_LIBS += [ 
     'mfbt', 
    ] 
else: 
    CONFIGURE_SUBST_FILES += [ 
     '../../config/autoconf-js.mk', 
     '../../config/emptyvars-js.mk', 
    ] 

あなたが持っているでしょう再建後:

$nm -gC libmozjs-45.so | grep HashBytes 
0000000000b66e07 T mozilla::HashBytes(void const*, unsigned long)