[LLVMdev] MCJIT longjmp failure on Win64 - was Invalid or unaligned stack exception on Windows
Paweł Bylica
chfast at gmail.com
Tue Apr 28 02:43:38 PDT 2015
On Tue, Apr 28, 2015 at 11:01 AM Dibyendu Majumdar <mobile at majumdar.org.uk>
wrote:
> On 28 April 2015 at 00:30, Reid Kleckner <rnk at google.com> wrote:
> > I think Paweł identified the problem. The frames on the stack between the
> > setjmp and longjmp must have valid unwind information, which is described
> > here:
> >
> https://msdn.microsoft.com/en-us/library/ft9x1kdx.aspx?f=255&MSPPError=-2147217396
> >
> > In particular, it has this line about JITed code:
> > "For dynamically generated functions [JIT compilers], the runtime to
> > support these functions must either use RtlInstallFunctionTableCallback
> or
> > RtlAddFunctionTable to provide this information to the operating system.
> > Failure to do so will result in unreliable exception handling and
> debugging
> > of processes."
> >
> > LLVM does not contain any references to these functions, so I must
> conclude
> > that unwinding through LLVM JITed frames on Win64 is not supported.
> Sorry.
> > :-(
> >
>
> Now that I know what to look for it seems there are a number of posts
> on this issue:
>
> http://lists.cs.uiuc.edu/pipermail/llvmdev/2014-October/078332.html
>
> I am changing the subject so that more people can find this topic.
>
>
> Re your suggestion to use my own longjmp/setjmp - do you mean I should
> use the LLVM intrinsics? But would they not call the Windows API
> anyway?
>
I'm not sure what your requirements are. Can you specify why do you need
longjmp?
The issue is your jump from longjmp call to setjmp location is crossing
functions on callstack that were created by MCJIT. Those functions do not
have proper stack unwinding information required by longjmp. The callstack
looks like:
setjmp, MSVC/C++
other code, LLVM MCJIT
longjmp, MSVC/C++
Your solutions are:
1. Pull longjmp call from C++ to LLVM IR. LLVM has a convenient
intrinsic for that: llvm.longjmp. That solution is a bit fragile as that
intrinsic will be lowered to C standard lib call, but if I remember
correctly it worked for me. Windows might have 3 different implementation
of longjmp: debug and release versions for C++ and C, maybe one of them is
less fussy.
2. Pull both longjmp and setjmp to LLVM IR. In that case you can switch
from full-featured versions powered by standard library to lightweight
builtin versions powered by LLVM (llvm.eh.sjlj.longjmp). Much better
portability.
In that second case, setting up llvm.eh.sjlj.setjmp correctly is a bit
tricky. You need to place some data (as stack pointer) in the jump buffer
manually. See
http://lists.cs.uiuc.edu/pipermail/llvmdev/2015-February/081961.html
I am also wondering if mingw gcc compilers have the same issue.
>
MinGW has its own implementation of setjmp/longjmp. Its longjmp do not do
C++ stack unwinding of course.
- Paweł
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20150428/087fb117/attachment.html>
More information about the llvm-dev
mailing list