runtime: Assertion of emitLocation causes BAD_ACCESS fault

Description

The JIT is being used to compile some custom instructions from a project (https://github.com/microsoft/pyjion) and I’m working on updating it from .NET Core 1.0.0rc2 all the way to .NET 5. The branch in question is here https://github.com/microsoft/Pyjion/pull/237

The emitter causes a bad access fault during the unwind phase:

bool Valid() const
    {
        // Things we could validate:
        //   1. the instruction group pointer is non-nullptr.
        //   2. 'ig' is a legal pointer to an instruction group.
        //   3. 'codePos' is a legal offset into 'ig'.
        // Currently, we just do #1.
        // #2 and #3 should only be done in DEBUG, if they are implemented.

>>  if (ig == nullptr)
        {
            return false;
        }

        return true;
    }

Exception: EXC_BAD_ACCESS (code=EXC_I386_GPFLT)

This is because emitLocation is an invalid memory address. Its being called from here:

UNATIVE_OFFSET emitLocation::CodeOffset(emitter* emit) const
{
    assert(Valid());
    return emit->emitCodeOffset(ig, codePos);
}

In the case of the fault, it happens in assert(Valid()), not because the assertion fails, but because it cannot read from the emitLocation because it is an invalid memory address. There is no assertion prior to this point to validate the emitLocation pointer, causing a crash.

Configuration

  • .NET 5.0 (release/5.0) compiled from source in debug configuration
  • macOS 10.15.7

CLR Flags

CORJIT_FLAG_SKIP_VERIFICATION
CORJIT_FLAG_DEBUG_CODE
CORJIT_FLAG_NO_INLINING
CORJIT_FLAG_MIN_OPT

JIT Settings

JitLsraStats= 1;
DumpJittedMethods = 1;
JitDumpToDebugger = 1;
JitDumpASCII = 1;
JitDump = u"methodname"

Regression?

This previously worked in .NET core 1.0.0rc2 (sorry!)

Other information

Stack trace

emitLocation::Valid() const emit.h:183
emitLocation::CodeOffset(emitter*) const emit.cpp:44
Compiler::unwindEmitFuncHelper(FuncInfoDsc*, void*, void*, bool) unwindamd64.cpp:766
Compiler::unwindEmitFunc(FuncInfoDsc*, void*, void*) unwindamd64.cpp:883
Compiler::unwindEmit(void*, void*) unwindamd64.cpp:736
CodeGen::genEmitUnwindDebugGCandEH() codegencommon.cpp:2396
CodeGenPhase::DoPhase() codegen.h:1605
Phase::Run() phase.cpp:61
DoPhase(CodeGen*, Phases, void (CodeGen::*)()) codegen.h:1619
CodeGen::genGenerateCode(void**, unsigned int*) codegencommon.cpp:2053
Compiler::compCompile(void**, unsigned int*, JitFlags*) compiler.cpp:4942
Compiler::compCompileHelper(CORINFO_MODULE_STRUCT_*, ICorJitInfo*, CORINFO_METHOD_INFO*, void**, unsigned int*, JitFlags*) compiler.cpp:6129
Compiler::compCompile(CORINFO_MODULE_STRUCT_*, void**, unsigned int*, JitFlags*)::$_12::operator()(Compiler::compCompile(CORINFO_MODULE_STRUCT_*, void**, unsigned int*, JitFlags*)::__JITParam*) const compiler.cpp:5468
Compiler::compCompile(CORINFO_MODULE_STRUCT_*, void**, unsigned int*, JitFlags*) compiler.cpp:5487
jitNativeCode(CORINFO_METHOD_STRUCT_*, CORINFO_MODULE_STRUCT_*, ICorJitInfo*, CORINFO_METHOD_INFO*, void**, unsigned int*, JitFlags*, void*)::$_15::operator()(jitNativeCode(CORINFO_METHOD_STRUCT_*, CORINFO_MODULE_STRUCT_*, ICorJitInfo*, CORINFO_METHOD_INFO*, void**, unsigned int*, JitFlags*, void*)::__JITParam*) const::'lambda'(jitNativeCode(CORINFO_METHOD_STRUCT_*, CORINFO_MODULE_STRUCT_*, ICorJitInfo*, CORINFO_METHOD_INFO*, void**, unsigned int*, JitFlags*, void*)::$_15::operator()(jitNativeCode(CORINFO_METHOD_STRUCT_*, CORINFO_MODULE_STRUCT_*, ICorJitInfo*, CORINFO_METHOD_INFO*, void**, unsigned int*, JitFlags*, void*)::__JITParam*) const::__JITParam*)::operator()(jitNativeCode(CORINFO_METHOD_STRUCT_*, CORINFO_MODULE_STRUCT_*, ICorJitInfo*, CORINFO_METHOD_INFO*, void**, unsigned int*, JitFlags*, void*)::$_15::operator()(jitNativeCode(CORINFO_METHOD_STRUCT_*, CORINFO_MODULE_STRUCT_*, ICorJitInfo*, CORINFO_METHOD_INFO*, void**, unsigned int*, JitFlags*, void*)::__JITParam*) const::__JITParam*) const compiler.cpp:6771
jitNativeCode(CORINFO_METHOD_STRUCT_*, CORINFO_MODULE_STRUCT_*, ICorJitInfo*, CORINFO_METHOD_INFO*, void**, unsigned int*, JitFlags*, void*)::$_15::operator()(jitNativeCode(CORINFO_METHOD_STRUCT_*, CORINFO_MODULE_STRUCT_*, ICorJitInfo*, CORINFO_METHOD_INFO*, void**, unsigned int*, JitFlags*, void*)::__JITParam*) const compiler.cpp:6796
jitNativeCode(CORINFO_METHOD_STRUCT_*, CORINFO_MODULE_STRUCT_*, ICorJitInfo*, CORINFO_METHOD_INFO*, void**, unsigned int*, JitFlags*, void*) compiler.cpp:6798
CILJit::compileMethod(ICorJitInfo*, CORINFO_METHOD_INFO*, unsigned int, unsigned char**, unsigned int*) ee_il_dll.cpp:273
ILGenerator::compile(ICorJitInfo*, ICorJitCompiler*, int) ilgen.h:486
PythonCompiler::emit_compile() pycomp.cpp:1124
AbstractInterpreter::compile_worker() absint.cpp:2650
AbstractInterpreter::compile() absint.cpp:3039
Jit_EvalTrace(PyjionJittedCode*, _frame*) pyjit.cpp:368
PyJit_EvalFrame(_ts*, _frame*, int) pyjit.cpp:520
_PyEval_EvalCode 0x0000000104258523
PyEval_EvalCode 0x000000010424e9ab
PyRun_InteractiveOneObjectEx 0x00000001042a0df9
PyRun_InteractiveLoopFlags 0x00000001042a0502
PyRun_AnyFileExFlags 0x00000001042a03ec
Py_RunMain 0x00000001042bdada
pymain_main 0x00000001042bdc3f
Py_BytesMain 0x00000001042bde3b
main python.c:15
start 0x00007fff6745bcc9

stdout/err

CLFLG_MINOPT set for method modulename:methodname(long,long):long
IL Code Size,Instr  131,  55, Basic Block count   6, Local Variable Num,Ref count   6, 10 for method modulename:methodname(long,long):long
IL Code Size,Instr  131,  55, Basic Block count   6, Local Variable Num,Ref count   6, 10 for method modulename:methodname(long,long):long
----------
LSRA Stats
----------
Total Tracked Vars:  0
Total Reg Cand Vars: 0
Total number of Intervals: 36
Total number of RefPositions: 135
Total Spill Count: 0    Weighted: 0
Total CopyReg Count: 0   Weighted: 0
Total ResolutionMov Count: 0    Weighted: 0
Total number of split edges: 0
Total Number of spill temps created: 0

Exception: EXC_BAD_ACCESS (code=EXC_I386_GPFLT)

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 32 (32 by maintainers)

Most upvoted comments

Never mind, figured it out… looks like I can repro (?):

Python 3.9.0rc2 (v3.9.0rc2:2bd31b5fde, Sep 16 2020, 20:19:18) 
[Clang 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import pyjion
>>> pyjion.enable()
True
>>> a = 1
Tracing <module> from <stdin> line 1 #1 (0 failures so far)
Calling first <module> from <stdin> line 1 0x7f9f7e527050
Processing OPCODE LOAD_CONST
Processing OPCODE STORE_NAME
Processing OPCODE LOAD_CONST
Processing OPCODE RETURN_VALUE
Bus error: 10

To get past the “jit failed” you need to set the OS type in getEEInfo. Since you’re on a mac, set it to unix for now:

pEEInfoOut->osType = CORINFO_UNIX;

With the above fixes it looks like it’s trying to run the jitted code, but still no joy:

'****** DONE compiling modulename:methodname(long,long):long
Tracing <module> from <stdin> line 1 
Invoking trace <module> from <stdin> line 1 0x0 0x10f14eb30
Segmentation fault: 11