2016-11-11 8 views
2

나는 SpiderMonkey가 내장 된 간단한 C++ 프로그램을 작성 중이다. 죄송합니다. JS_NewContext()에 있습니다. (jsapi_use.cpp로 저장)JSAPI segfault in JS_NewContext

이 프로그램은 :

#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에서 충돌합니다.

내 메이크 : 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를 내부에 깊은 segfaulting 것을 알 수있다.

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 편집보기 – 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 파일을 변경하고 스파이더 맨 키를 다시 작성하면됩니다.

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)