Uh oh!
There was an error while loading. Please reload this page.
Fix crossgen2 JitHost OOM crash: throw on allocation failure - #125422
Conversation
crossgen2's JitHost::allocateMemory returned NULL from malloc on OOM, unlike the CoreCLR VM host which uses 'new' (throws bad_alloc). The JIT's ArenaAllocator::allocateNewPage assumes the allocator either succeeds or throws, and immediately dereferences the result without a NULL check, causing an access violation. Throw std::bad_alloc on NULL returns from malloc/calloc so OOM is handled consistently across all JIT hosts. Also catch std::bad_alloc at the JitCompileMethod boundary in jitwrapper.cpp and return CORJIT_OUTOFMEM so the managed caller gets a proper error code instead of an unhandled native exception. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
jtschuster
commented
Mar 11, 2026
/azp run runtime-coreclr crossgen2-composite |
|
Azure Pipelines successfully started running 1 pipeline(s). |
There was a problem hiding this comment.
Pull request overview
Fixes crossgen2 JitHost out-of-memory behavior by converting allocation failures into std::bad_alloc, and translating those into a JIT “out of memory” result at the JitCompileMethod boundary.
Changes:
- Throw
std::bad_allocwhenmalloc/callocreturnnullptrin the crossgen2 JIT host. - Catch
std::bad_allocinJitCompileMethodand return an out-of-memory status code. - Add
<new>includes forstd::bad_alloc.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| src/coreclr/tools/aot/jitinterface/jitwrapper.cpp | Catches OOM exceptions at the compile boundary and returns an OOM result. |
| src/coreclr/tools/aot/jitinterface/jithost.cpp | Makes host allocations throw on failure instead of returning nullptr. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch |
crossgen2's JitHost::allocateMemory returned NULL from malloc on OOM, unlike the CoreCLR VM host which uses 'new' (throws bad_alloc). The JIT's ArenaAllocator::allocateNewPage assumes the allocator either succeeds or throws, and immediately dereferences the result without a NULL check, causing an access violation. Throw std::bad_alloc on NULL returns from malloc/calloc so OOM is handled consistently across all JIT hosts. Also catch std::bad_alloc at the JitCompileMethod boundary in jitwrapper.cpp and return CORJIT_OUTOFMEM so the managed caller gets a proper error code instead of an unhandled native exception. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Uh oh!
There was an error while loading. Please reload this page.
Replace malloc/free with new/delete in crossgen2's jithost.cpp so that OOM throws std::bad_alloc (caught by jitwrapper.cpp as CORJIT_OUTOFMEM) instead of returning null and crashing. Translate CORJIT_OUTOFMEM to OutOfMemoryException in CorInfoImpl.cs so crossgen2 can skip failed methods gracefully. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…chuster/runtime into fix/crossgen2-oom-null-deref
Uh oh!
There was an error while loading. Please reload this page.
The removal of <stdlib.h> (which transitively provided size_t) caused a build failure on Linux where dllexport.h alone does not pull in size_t. Add <stddef.h> which is the minimal header for size_t without pulling in malloc/free. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…chuster/runtime into fix/crossgen2-oom-null-deref
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
Comments suppressed due to low confidence (1)
src/coreclr/tools/aot/jitinterface/jitwrapper.cpp:14
- In the
std::bad_alloccatch path,ppExceptionis not set before returning, which can leave the out-parameter in an indeterminate state for the caller. Consider explicitly clearing it (e.g., set*ppException = nullptrwhenppExceptionis non-null) before returningCORJIT_OUTOFMEM.
DLL_EXPORT int JitCompileMethod(
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
crossgen2's JitHost::allocateMemory returned NULL from malloc on OOM, unlike the CoreCLR VM host which uses 'new' (which throws bad_alloc). The JIT's ArenaAllocator::allocateNewPage assumes the allocator either succeeds or throws, and immediately dereferences the result without a NULL check, causing an access violation. This is happening in crossgen outerloops on ARM and x86. This change should help make those failures more obvious.
Throw std::bad_alloc on NULL returns from malloc/calloc so OOM is handled consistently across all JIT hosts. Also catch std::bad_alloc at the JitCompileMethod boundary in jitwrapper.cpp and return CORJIT_OUTOFMEM so the managed caller gets a proper error code instead of an unhandled native exception.