[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