chakra-core / chakra-core/ChakraCore

Crash due to Assertion in `GlobalOpt::CollectMemOpInfo`

Open
#6,676 1 comment 0 reactions 0 assignees View on GitHub
Bug Severity: 2
Dominant language
JavaScript
Stars
9.3k
Forks
1.2k
PR merge metrics
No merged PRs in 30d

Description

poc:

```c
function main() {
for (let v3 = -2; v3 < 1337; v3 = v3 + 0) {
const v4 = v3++;
}
}
main();
```

backtrace is:
```
(gdb) bt
#0 0x000055cd2ac3320a in GlobOpt::CollectMemOpInfo (this=0x7fb322aeefd0, instrBegin=, instr=, src1Val=0x7fb324fbd270, src2Val=) at /src/chakracore/lib/Backend/GlobOpt.cpp:2360
#1 0x000055cd2abf1ea0 in GlobOpt::OptInstr (this=0x7fb322aeefd0, instr=, isInstrRemoved=0x7fb322aedd20) at /src/chakracore/lib/Backend/GlobOpt.cpp:2739
#2 0x000055cd2abe17a7 in GlobOpt::OptBlock (this=, block=0x7fb324fb3508) at /src/chakracore/lib/Backend/GlobOpt.cpp:520
#3 0x000055cd2abdbcd7 in GlobOpt::ForwardPass (this=0x7fb322aeefd0) at /src/chakracore/lib/Backend/GlobOpt.cpp:401
#4 0x000055cd2abd8637 in GlobOpt::Optimize (this=) at /src/chakracore/lib/Backend/GlobOpt.cpp:211
#5 0x000055cd2ab831c7 in Func::TryCodegen (this=) at /src/chakracore/lib/Backend/Func.cpp:457
#6 0x000055cd2ab819f8 in Func::Codegen (alloc=0x7fb322af04a0, workItem=0x7fb324fa1030, threadContextInfo=0x623000000198, scriptContextInfo=0x622000000158, outputData=0x7fb322af0740, epInfo=0x7fb325165180, runtimeInfo=,
polymorphicInlineCacheInfo=, codeGenAllocators=, codeGenProfiler=, isBackgroundJIT=) at /src/chakracore/lib/Backend/Func.cpp:325
#7 0x000055cd2a62990f in NativeCodeGenerator::CodeGen (this=, pageAllocator=, workItemData=0x612000000540, jitWriteData=..., foreground=false, epInfo=0x7fb325165180) at /src/chakracore/lib/Backend/NativeCodeGenerator.cpp:890
#8 0x000055cd2a62eaf8 in NativeCodeGenerator::CodeGen (this=0x6130000005d8, pageAllocator=, workItem=, foreground=64) at /src/chakracore/lib/Backend/NativeCodeGenerator.cpp:1007
#9 0x000055cd2a637e80 in NativeCodeGenerator::Process (this=, job=, threadData=0x615000002658) at /src/chakracore/lib/Backend/NativeCodeGenerator.cpp:1907
#10 0x000055cd2a77bad4 in JsUtil::BackgroundJobProcessor::Process (this=, job=, threadData=0x615000002658) at /src/chakracore/lib/Common/Common/Jobs.cpp:1037
#11 0x000055cd2a77c2ad in JsUtil::BackgroundJobProcessor::Run (this=0x612000000098, threadData=) at /src/chakracore/lib/Common/Common/Jobs.cpp:1135
#12 0x000055cd2a7740d0 in JsUtil::BackgroundJobProcessor::StaticThreadProc (lpParam=) at /src/chakracore/lib/Common/Common/Jobs.cpp:1319
#13 0x000055cd26fc3adb in CorUnix::CPalThread::ThreadEntry (pvParam=0x61c000001880) at /src/chakracore/pal/src/thread/pal_thread.cpp:1605
#14 0x000055cd26e2df3f in __asan::AsanThread::ThreadStart(unsigned long, __sanitizer::atomic_uintptr_t*) ()
#15 0x00007fb32a3986db in start_thread (arg=0x7fb322af1700) at pthread_create.c:463
#16 0x00007fb32990771f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
```

The source code of the assertion is:
```c++
// If an instr where the dst is an induction variable (and thus is being written to) is not caught by a case in the above
// switch statement (which implies that this instr does not contributes to a inductionVariableChangeInfo) and in the default
// case does not set doMemOp to false (which implies that this instr does not invalidate this MemOp), then FailFast as we
// should not be performing a MemOp under these conditions.
AssertOrFailFast(!instr->GetDst() || instr->m_opcode == Js::OpCode::IncrLoopBodyCount || !loop->memOpInfo ||

// Refer to "Case #2" described above in this function. For the following IR:
// Line #1: s4(s2) = Add_I4 s3(s1) 1
// Line #2: s3(s1) = Ld_A s4(s2)
// do not consider line #2 as a violating instr
(instr->m_opcode == Js::OpCode::Ld_I4 &&
prevInstr && (prevInstr->m_opcode == Js::OpCode::Add_I4 || prevInstr->m_opcode == Js::OpCode::Sub_I4) &&
instr->GetSrc1()->IsRegOpnd() &&
instr->GetDst()->IsRegOpnd() &&
prevInstr->GetDst()->IsRegOpnd() &&
instr->GetDst()->GetStackSym() == prevInstr->GetSrc1()->GetStackSym() &&
instr->GetSrc1()->GetStackSym() == prevInstr->GetDst()->GetStackSym()) ||

!loop->memOpInfo->inductionVariableChangeInfoMap->ContainsKey(GetVarSymID(instr->GetDst()->GetStackSym())));
```

Contributor guide

Open the contributing guide

Research direction

Reproduce the crash with the JavaScript PoC, then inspect lib/Backend/GlobOpt.cpp at CollectMemOpInfo around line 2360 and its caller OptInstr. Trace the induction-variable and memory-operation state for this loop. Done means the PoC no longer triggers the assertion, with regression coverage for the failing case.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp, javascript
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.