-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Assertion of emitLocation causes BAD_ACCESS fault #42925
Comments
Compiler::unwindEmitFuncHelper
{
...
if (func->startLoc == nullptr)
{
startOffset = 0;
}
else
{
startOffset = func->startLoc->CodeOffset(GetEmitter());
} seems a little odd we end up calling Can you add repro instructions? Does this repro every time? |
@AndyAyersMS
I thought this maybe PIC/PIE related, but the caller to the JIT compiled with |
The So the failure you're seeing above seems like it could be some sort of memory corruption. Does it always fail the same way? |
this repros every time in exactly the same way. this is a library using the JIT ( repro steps: $ python3.9
>>> import pyjion
>>> pyjion.enable()
>>> a = 1
|
Ok, let me see if I can repro. |
Wow! thank you. I can put a breakpoint into |
Some additional steps for setup:
|
What exactly do I need to do for this step? |
Never mind, figured it out... looks like I can repro (?):
|
Debugging, my error looks a bit different than the one you reported above, but perhaps they're related. In both cases the emitter is failing. You need to implement Ideally code and data blocks also have the requested alignment, and the code block should also be executable. |
@AndyAyersMS aha!! that makes sense and explains the corrupt memory address. I've implemented it using Python's pool-based memory allocator, which has an alignment of 16 (fixed). It doesn't crash anymore, but it raises an exception. This one is much more verbose so I'll keep shaving this yak :-)
|
I looked at this next failure a bit but ended up wondering what IL was being emitted, and got distracted trying to figure out why I couldn't enable regular jit dumps (which among other things would show the IL). I think there's something off with the implementation of It would also probably be worthwhile to read the environment variables looking for |
Ah yes thanks. Made that change microsoft/Pyjion@30d8423 Can't see the JitDump yet but I can tell that its matching the values correctly |
I'm stuck on void Compiler::unwindEmitFuncHelper(FuncInfoDsc* func, void* pHotCode, void* pColdCode, bool isHotCode)
{
...
assert(fgFirstColdBlock != nullptr); The firstColdBlock is a nullptr. I'm not sure where it gets that address from? |
Are you emitting IL with EH regions / opcodes? We would not expect to be looking for cold blocks/funclets unless there was some kind of EH. That's the question I was trying to ask when I got sidetracked with enabling dumping. |
Yes, thats in absint.h/absint.cpp. I'm trying to revitalise this 4-year old code base, so there have also been some major changes to CPython's opcodes |
To get dumping working, you need to return
|
To fix the asserts, only allocate the cold block and ro data block if the sizes are nonzero:
otherwise the jit gets confused and thinks there should be cold code. |
To get past the "jit failed" you need to set the OS type in
With the above fixes it looks like it's trying to run the jitted code, but still no joy:
|
Ah yes, thats a "feature" of the PyMem_Alloc functions, they allocate 0-size blocks as a way of better handling null-references |
That all worked! I'm up to the SEG fault but with the breakpoints, I can see it hasn't properly resolved the code address. There are still some failing assertions but I've put warnings on all the unimplemented methods to better get an idea on the issue
|
What does |
This compiler->compGetHelperFtn((CorInfoHelpFunc)helper, &pAddr |
Figured out I can just |
Nearly there the |
@AndyAyersMS try microsoft/Pyjion@1a09ff1 I've set the right pointer to the hot code address. It doesn't execute (faults with bad access), so maybe the memory is allocated with the wrong flags, or its the wrong size |
It gives the jit the address of a helper method. If you look at the jitted code one of the first things is
and the jit is asking the runtime for the address of this helper. For this helper, you can return the address of a do-nothing The memory you allocate for the jit needs to have execute permissions; normally allocated blocks don't have this. I don't know the python hosting API well enough to know if there's something you can use. Also OSX may be finicky about giving out pages that are both writeable and executable. |
@AndyAyersMS I saw that VirtualAlloc() is implemented cross-platform and part of the PAL APIs, but I can't see where the symbol gets built so I can link it and use that function to allocate executable memory |
@AndyAyersMS it works now :-) feel free to give it a go! there's loads of bugs but its evaluating the JIT'ed code on OSX and interacting with the CPython methods. |
Very cool! Glad to help. |
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 microsoft/Pyjion#237
The emitter causes a bad access fault during the unwind phase:
Exception: EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
This is because
emitLocation
is an invalid memory address. Its being called from here: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
CLR Flags
JIT Settings
Regression?
This previously worked in .NET core 1.0.0rc2 (sorry!)
Other information
Stack trace
stdout/err
The text was updated successfully, but these errors were encountered: