chakra-core / ChakraCore

ChakraCore is an open source Javascript engine with a C API.
MIT License
9.11k stars 1.2k forks source link

Assertion Failure: IsUninitialized() || IsLikelyInt() when GlobOpt tries hoist invariant #6903

Open JimWongM opened 1 year ago

JimWongM commented 1 year ago

Version

commit id: c3ead3f8a6e0bb8e32e043adc091c68cba5935e9

Platform

Ubuntu 20.04.5 LTS (Linux 5.4.0-144-generic x86_64)

Build

./build.sh --debug --static

PoC

for (let i = 0; i < 10; i++) {
    for (let j = 0; j < 10; j++) {
        function opt() {
            i[1] = 2
        }
        switch (i) {
            case -3124201329:
                break;
            case i:
                break;
        }
    }
}

Execution steps & Output

./ch --maxinterpretcount:10 --maxsimplejitruncount:100 -bgjit- poc.js
ASSERTION 373997: (/home/wjm/ChakraCore/lib/Backend/ValueInfo.cpp, line 561) IsUninitialized() || IsLikelyInt() || isForLoopBackEdgeCompensation
 Failure: (IsUninitialized() || IsLikelyInt() || isForLoopBackEdgeCompensation)
Signal: SIGILL (Illegal instruction)

Backtrace

(lldb) thread backtrace
* thread #1, name = 'ch', stop reason = signal SIGILL: illegal instruction operand
  * frame #0: 0x0000555556d070df ch`ValueInfo::SpecializeToInt32(this=0x00007ff7e7bb8d40, allocator=0x00007fffffff8d18, isForLoopBackEdgeCompensation=false) at ValueInfo.cpp:561:5
    frame #1: 0x0000555556b87ee5 ch`GlobOpt::OptHoistInvariant(this=0x00007fffffff9850, instr=0x00007ff7e7bb96a8, block=0x00007ff7e7c0a288, loop=0x00007ff7e7c0b160, dstVal=0x00007ff7e7bbaa70, src1Val=0x00007ff7e7bbaa70, src2Val=0x0000000000000000, isNotTypeSpecConv=false, lossy=false, bailoutKind=BailOutIntOnly) at GlobOpt.cpp:15538:44
    frame #2: 0x0000555556b63748 ch`GlobOpt::TryHoistInvariant(this=0x00007fffffff9850, instr=0x00007ff7e7bb96a8, block=0x00007ff7e7c0a288, dstVal=0x00007ff7e7bbaa70, src1Val=0x00007ff7e7bbaa70, src2Val=0x0000000000000000, isNotTypeSpecConv=false, lossy=false, forceInvariantHoisting=false, bailoutKind=BailOutIntOnly) at GlobOpt.cpp:15601:9
    frame #3: 0x0000555556b51049 ch`GlobOpt::ToTypeSpecUse(this=0x00007fffffff9850, instr=0x00007ff7e7bf6eb0, opnd=0x00007ff7e7bb9548, block=0x00007ff7e7c0a288, val=0x00007ff7e7bbaa70, indir=0x0000000000000000, toType=TyInt32, bailOutKind=BailOutIntOnly, lossy=false, insertBeforeInstr=0x00007ff7e7bf6eb0) at GlobOpt.cpp:12048:31
    frame #4: 0x0000555556b80455 ch`GlobOpt::ToInt32(this=0x00007fffffff9850, instr=0x00007ff7e7bf6eb0, opnd=0x00007ff7e7bf6e70, block=0x00007ff7e7c0a288, val=0x00007ff7e7bbaa70, indir=0x0000000000000000, lossy=false) at GlobOpt.cpp:11536:18
    frame #5: 0x0000555556b7aa6e ch`GlobOpt::OptConstFoldBr(this=0x00007fffffff9850, test=true, instr=0x00007ff7e7bf6eb0, src1Val=0x00007ff7e7bbaa70, src2Val=0x00007ff7e7bbaa70) at GlobOpt.cpp:12605:15
    frame #6: 0x0000555556b83df2 ch`GlobOpt::TryOptConstFoldBrEqual(this=0x00007fffffff9850, instr=0x00007ff7e7bf6eb0, branchOnEqual=true, src1Value=0x00007ff7e7bbaa70, min1=-2147483648, max1=2147483647, src2Value=0x00007ff7e7bbaa70, min2=-2147483648, max2=2147483647) at GlobOpt.cpp:10242:9
    frame #7: 0x0000555556b752f1 ch`GlobOpt::TypeSpecializeBinary(this=0x00007fffffff9850, pInstr=0x00007fffffff82b8, pSrc1Val=0x00007fffffff8560, pSrc2Val=0x00007fffffff8558, pDstVal=0x00007fffffff8550, src1OriginalVal=0x00007ff7e7bbaa70, src2OriginalVal=0x00007ff7e7bbaa70, redoTypeSpecRef=0x00007fffffff8511) at GlobOpt.cpp:9844:21
    frame #8: 0x0000555556b6113b ch`GlobOpt::TypeSpecialization(this=0x00007fffffff9850, instr=0x00007ff7e7bf6eb0, pSrc1Val=0x00007fffffff8560, pSrc2Val=0x00007fffffff8558, pDstVal=0x00007fffffff8550, redoTypeSpecRef=0x00007fffffff8511, forceInvariantHoistingRef=0x00007fffffff8513) at GlobOpt.cpp:6382:35
    frame #9: 0x0000555556b4a409 ch`GlobOpt::OptInstr(this=0x00007fffffff9850, instr=0x00007fffffff86c8, isInstrRemoved=0x00007fffffff86be) at GlobOpt.cpp:2633:23
    frame #10: 0x0000555556b46dce ch`GlobOpt::OptBlock(this=0x00007fffffff9850, block=0x00007ff7e7c0a288) at GlobOpt.cpp:521:27
    frame #11: 0x0000555556b458a7 ch`GlobOpt::ForwardPass(this=0x00007fffffff9850) at GlobOpt.cpp:402:15
    frame #12: 0x0000555556b44ab3 ch`GlobOpt::Optimize(this=0x00007fffffff9850) at GlobOpt.cpp:212:15
    frame #13: 0x0000555556b262ab ch`Func::TryCodegen(this=0x00007fffffff9f00) at Func.cpp:457:21
    frame #14: 0x0000555556b25ae0 ch`Func::Codegen(alloc=0x00007fffffffa4c0, workItem=0x00007ff7e7bf4030, threadContextInfo=0x0000555557eb7068, scriptContextInfo=0x0000555557ee8fe8, outputData=0x00007fffffffa900, epInfo=0x00007ff7e7c64200, runtimeInfo=0x0000000000000000, polymorphicInlineCacheInfo=0x00007ff7e7c3f420, codeGenAllocators=0x0000555557ef5db8, codeGenProfiler=0x0000000000000000, isBackgroundJIT=false) at Func.cpp:325:18
    frame #15: 0x000055555690ef90 ch`NativeCodeGenerator::CodeGen(this=0x0000555557eea7b8, pageAllocator=0x0000555557eb73f0, workItemData=0x0000555557ef5cb0, jitWriteData=0x00007fffffffa900, foreground=true, epInfo=0x00007ff7e7c64200) at NativeCodeGenerator.cpp:890:9
    frame #16: 0x0000555556910c28 ch`NativeCodeGenerator::CodeGen(this=0x0000555557eea7b8, pageAllocator=0x0000555557eb73f0, workItem=0x0000555557ef5c88, foreground=true) at NativeCodeGenerator.cpp:1007:5
    frame #17: 0x00005555569139a7 ch`NativeCodeGenerator::Process(this=0x0000555557eea7b8, job=0x0000555557ef5c90, threadData=0x0000000000000000) at NativeCodeGenerator.cpp:1895:13
    frame #18: 0x00005555569b83d4 ch`JsUtil::ForegroundJobProcessor::Process(job=0x0000555557ef5c90) at Jobs.cpp:426:36
    frame #19: 0x0000555556922bc3 ch`void JsUtil::ForegroundJobProcessor::PrioritizeJobAndWait<NativeCodeGenerator, Js::EntryPointInfo*>(this=0x0000555557ea2ce8, manager=0x0000555557eea7b8, holder=0x00007ff7e7c64200, function=0x0000000000000000) at Jobs.inl:207:36
    frame #20: 0x0000555556918804 ch`void JsUtil::JobProcessor::PrioritizeJobAndWait<NativeCodeGenerator, Js::EntryPointInfo*>(this=0x0000555557ea2ce8, manager=0x0000555557eea7b8, holder=0x00007ff7e7c64200, function=0x0000000000000000) at Jobs.inl:81:58
    frame #21: 0x000055555690d4fc ch`NativeCodeGenerator::GenerateLoopBody(this=0x0000555557eea7b8, fn=0x00007ff7e7c47000, loopHeader=0x00007ff7e7c62270, entryPoint=0x00007ff7e7c64200, localCount=15, localSlots=0x00007fffffffc140) at NativeCodeGenerator.cpp:711:22
    frame #22: 0x00005555568157dd ch`GenerateLoopBody(nativeCodeGen=0x0000555557eea7b8, fn=0x00007ff7e7c47000, loopHeader=0x00007ff7e7c62270, info=0x00007ff7e7c64200, localCount=15, localSlots=0x00007fffffffc140) at BackendApi.cpp:88:20
    frame #23: 0x0000555555fb220b ch`Js::InterpreterStackFrame::DoLoopBodyStart(this=0x00007fffffffbfe0, loopNumber=1, layoutSize=SmallLayout, doProfileLoopCheck=false, isFirstIteration=false) at InterpreterStackFrame.cpp:6277:17
    frame #24: 0x0000555555fb57ee ch`void Js::InterpreterStackFrame::ProfiledLoopBodyStart<false, true>(this=0x00007fffffffbfe0, loopNumber=1, layoutSize=SmallLayout, isFirstIteration=false) at InterpreterStackFrame.cpp:5930:41
    frame #25: 0x0000555555ff8a0a ch`unsigned char const* Js::InterpreterStackFrame::OP_ProfiledLoopBodyStart<(Js::LayoutSize)0, true>(this=0x00007fffffffbfe0, loopId=1) at InterpreterStackFrame.cpp:5902:9
    frame #26: 0x0000555555fc6a96 ch`unsigned char const* Js::InterpreterStackFrame::OP_ProfiledLoopBodyStart<(Js::LayoutSize)0, true>(this=0x00007fffffffbfe0, ip="\U00000012\U00000003") at InterpreterStackFrame.cpp:5774:16
    frame #27: 0x0000555555eaae91 ch`Js::InterpreterStackFrame::ProcessProfiled(this=0x00007fffffffbfe0) at InterpreterHandler.inl:52:3
    frame #28: 0x0000555555e525de ch`Js::InterpreterStackFrame::Process(this=0x00007fffffffbfe0) at InterpreterStackFrame.cpp:3520:22
    frame #29: 0x0000555555e50dd3 ch`Js::InterpreterStackFrame::InterpreterHelper(function=0x00007ff7e7c766e0, args=ArgumentReader @ 0x00007fffffffc530, returnAddress=0x00007ff7e7bd0fa2, addressOfReturnAddress=0x00007fffffffc578, asmJsReturn=0x0000000000000000) at InterpreterStackFrame.cpp:2153:40
    frame #30: 0x0000555555e4feb0 ch`Js::InterpreterStackFrame::InterpreterThunk(layout=0x00007fffffffc590) at InterpreterStackFrame.cpp:1833:16
    frame #31: 0x00007ff7e7bd0fa2
    frame #32: 0x00005555564a37de ch`amd64_CallFunction at JavascriptFunctionA.S:100
    frame #33: 0x00005555561d7a4b ch`void* Js::JavascriptFunction::CallFunction<true>(function=0x00007ff7e7c766e0, entryPoint=(ch`NativeCodeGenerator::CheckCodeGenThunk(Js::RecyclableObject*, Js::CallInfo, ...)), args=Arguments @ 0x00007fffffffc798, useLargeArgCount=false)(Js::RecyclableObject*, Js::CallInfo, ...), Js::Arguments, bool) at JavascriptFunction.cpp:1364:16
    frame #34: 0x00005555561cf2f4 ch`Js::JavascriptFunction::CallRootFunctionInternal(obj=0x00007ff7e7c766e0, args=Arguments @ 0x00007fffffffc810, scriptContext=0x0000555557ee8fe8, inScript=true) at JavascriptFunction.cpp:772:24
    frame #35: 0x00005555561cf10c ch`Js::JavascriptFunction::CallRootFunction(obj=0x00007ff7e7c766e0, args=<unavailable>, scriptContext=0x0000555557ee8fe8, inScript=true) at JavascriptFunction.cpp:717:15
    frame #36: 0x00005555561cf0b1 ch`Js::JavascriptFunction::CallRootFunction(this=0x00007ff7e7c766e0, args=<unavailable>, scriptContext=0x0000555557ee8fe8, inScript=true) at JavascriptFunction.cpp:832:16
    frame #37: 0x0000555555894a8e ch`RunScriptCore(this=0x00007fffffffcbe0, scriptContext=0x0000555557ee8fe8, _actionEntryPopper=0x00007fffffffcbc0)::$_85::operator()(Js::ScriptContext*, TTD::TTDJsRTActionResultAutoRecorder&) const at Jsrt.cpp:3705:49
    frame #38: 0x0000555555894624 ch`_JsErrorCode ContextAPIWrapper<false, RunScriptCore(void*, unsigned char const*, unsigned long, LoadScriptFlag, unsigned long, char16_t const*, bool, _JsParseScriptAttributes, bool, void**)::$_85>(this=0x00007fffffffcb78, scriptContext=0x0000555557ee8fe8)::$_85)::'lambda'(Js::ScriptContext*)::operator()(Js::ScriptContext*) const at JsrtInternal.h:237:16
    frame #39: 0x0000555555893fc4 ch`_JsErrorCode ContextAPIWrapper_Core<false, _JsErrorCode ContextAPIWrapper<false, RunScriptCore(void*, unsigned char const*, unsigned long, LoadScriptFlag, unsigned long, char16_t const*, bool, _JsParseScriptAttributes, bool, void**)::$_85>(RunScriptCore(void*, unsigned char const*, unsigned long, LoadScriptFlag, unsigned long, char16_t const*, bool, _JsParseScriptAttributes, bool, void**)::$_85)::'lambda'(Js::ScriptContext*)>(fn=(anonymous class) @ 0x00007fffffffcb78)::$_85) at JsrtInternal.h:192:23
    frame #40: 0x00005555558608f6 ch`_JsErrorCode ContextAPIWrapper<false, RunScriptCore(void*, unsigned char const*, unsigned long, LoadScriptFlag, unsigned long, char16_t const*, bool, _JsParseScriptAttributes, bool, void**)::$_85>(fn=(anonymous class) @ 0x00007fffffffcbe0)::$_85) at JsrtInternal.h:235:27
    frame #41: 0x00005555558607fb ch`RunScriptCore(scriptSource=0x00007ff7e7c44000, script="for (let i = 0; i < 10; i++) {\n    for (let j = 0; j < 10; j++) {\n        function opt() {\n            i[1] = 2\n        }\n        switch (i) {\n            case -3124201329:\n                break;\n            case i:\n                break;\n        }\n    }\n}\n// CRASH INFO\n// ==========\n// TERMSIG: 4\n// STDERR:\n// ASSERTION 641164: (/home/wjm/ChakraCore/lib/Backend/ValueInfo.cpp, line 561) IsUninitialized() || IsLikelyInt() || isForLoopBackEdgeCompensation\n//  Failure: (IsUninitialized() || IsLikelyInt() || isForLoopBackEdgeCompensation)\n// STDOUT:\n// ARGS: /home/wjm/ChakraCore/out/Debug/ch --maxinterpretcount:10 --maxsimplejitruncount:100 -bgjit- -reprl fuzzcode.js\n// EXECUTION TIME: 25 ms\n\n\n/*\n\nTitle: \n\n## Version\ncommit id: c3ead3f8a6e0bb8e32e043adc091c68cba5935e9\n\n## Platform\nUbuntu 20.04.5 LTS (Linux 5.4.0-144-generic x86_64)\n\n## Build\n- Debug Mode\n\n```\n./build.sh --debug --static\n```\n\n## PoC\n```\n\n```\n\n## Execution steps & Output\n```\n./ch --maxinterpretcount:10 --maxsimplejitruncount:100 -bgjit- poc.js\nAbor"..., cb=1072, loadScriptFlag=LoadScriptFlag_Utf8Source | LoadScriptFlag_ExternalArrayBuffer, sourceContext=0, sourceUrl=u"/home/wjm/DiTing-pocs/chakra/bug07_valueInfo.js", parseOnly=false, parseAttributes=JsParseScriptAttributeNone, isSourceModule=false, result=0x0000000000000000) at Jsrt.cpp:3656:12
    frame #42: 0x0000555555862f6e ch`::JsRun(JsValueRef, JsSourceContext, JsValueRef, JsParseScriptAttributes, JsValueRef *) [inlined] CompileRun(scriptVal=0x00007ff7e7c44000, sourceContext=0, sourceUrl=0x00007ff7e7c71cf0, parseAttributes=JsParseScriptAttributeNone, result=0x0000000000000000, parseOnly=false) at Jsrt.cpp:5019:12
    frame #43: 0x0000555555862db9 ch`::JsRun(scriptVal=0x00007ff7e7c44000, sourceContext=0, sourceUrl=0x00007ff7e7c71cf0, parseAttributes=JsParseScriptAttributeNone, result=0x0000000000000000) at Jsrt.cpp:5041
    frame #44: 0x0000555555787293 ch`ChakraRTInterface::JsRun(script=0x00007ff7e7c44000, sourceContext=0, sourceUrl=0x00007ff7e7c71cf0, parseAttributes=JsParseScriptAttributeNone, result=0x0000000000000000) at ChakraRtInterface.h:487:179
    frame #45: 0x0000555555784924 ch`RunScript(fileName="bug07_valueInfo.js", fileContents="for (let i = 0; i < 10; i++) {\n    for (let j = 0; j < 10; j++) {\n        function opt() {\n            i[1] = 2\n        }\n        switch (i) {\n            case -3124201329:\n                break;\n            case i:\n                break;\n        }\n    }\n}\n// CRASH INFO\n// ==========\n// TERMSIG: 4\n// STDERR:\n// ASSERTION 641164: (/home/wjm/ChakraCore/lib/Backend/ValueInfo.cpp, line 561) IsUninitialized() || IsLikelyInt() || isForLoopBackEdgeCompensation\n//  Failure: (IsUninitialized() || IsLikelyInt() || isForLoopBackEdgeCompensation)\n// STDOUT:\n// ARGS: /home/wjm/ChakraCore/out/Debug/ch --maxinterpretcount:10 --maxsimplejitruncount:100 -bgjit- -reprl fuzzcode.js\n// EXECUTION TIME: 25 ms\n\n\n/*\n\nTitle: \n\n## Version\ncommit id: c3ead3f8a6e0bb8e32e043adc091c68cba5935e9\n\n## Platform\nUbuntu 20.04.5 LTS (Linux 5.4.0-144-generic x86_64)\n\n## Build\n- Debug Mode\n\n```\n./build.sh --debug --static\n```\n\n## PoC\n```\n\n```\n\n## Execution steps & Output\n```\n./ch --maxinterpretcount:10 --maxsimplejitruncount:100 -bgjit- poc.js\nAbor"..., fileLength=1072, fileContentsFinalizeCallback=(ch`WScriptJsrt::FinalizeFree(void*) at WScriptJsrt.cpp:217), bufferValue=0x0000000000000000, fullPath="/home/wjm/DiTing-pocs/chakra/bug07_valueInfo.js", parserStateCache=0x0000000000000000)(void*), void*, char*, void*) at ch.cpp:451:25
    frame #46: 0x00005555557863f0 ch`ExecuteTest(fileName="bug07_valueInfo.js") at ch.cpp:917:13
    frame #47: 0x00005555557864ac ch`ExecuteTestWithMemoryCheck(fileName="bug07_valueInfo.js") at ch.cpp:967:10
    frame #48: 0x0000555555786d7a ch`main(argc=5, c_argv=0x00007fffffffd648) at ch.cpp:1274:20
    frame #49: 0x00007ffff778d1e2 libc.so.6`__libc_start_main + 242
    frame #50: 0x0000555555783b7e ch`_start + 46