<div dir="ltr"><div class="gmail_quote">On Tue, Apr 28, 2015 at 11:01 AM Dibyendu Majumdar <<a href="mailto:mobile@majumdar.org.uk" target="_blank">mobile@majumdar.org.uk</a>> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On 28 April 2015 at 00:30, Reid Kleckner <<a href="mailto:rnk@google.com" target="_blank">rnk@google.com</a>> wrote:<br>
> I think Paweł identified the problem. The frames on the stack between the<br>
> setjmp and longjmp must have valid unwind information, which is described<br>
> here:<br>
> <a href="https://msdn.microsoft.com/en-us/library/ft9x1kdx.aspx?f=255&MSPPError=-2147217396" target="_blank">https://msdn.microsoft.com/en-us/library/ft9x1kdx.aspx?f=255&MSPPError=-2147217396</a><br>
><br>
> In particular, it has this line about JITed code:<br>
>   "For dynamically generated functions [JIT compilers], the runtime to<br>
> support these functions must either use RtlInstallFunctionTableCallback or<br>
> RtlAddFunctionTable to provide this information to the operating system.<br>
> Failure to do so will result in unreliable exception handling and debugging<br>
> of processes."<br>
><br>
> LLVM does not contain any references to these functions, so I must conclude<br>
> that unwinding through LLVM JITed frames on Win64 is not supported. Sorry.<br>
> :-(<br>
><br>
<br>
Now that I know what to look for it seems there are a number of posts<br>
on this issue:<br>
<br>
<a href="http://lists.cs.uiuc.edu/pipermail/llvmdev/2014-October/078332.html" target="_blank">http://lists.cs.uiuc.edu/pipermail/llvmdev/2014-October/078332.html</a><br>
<br>
I am changing the subject so that more people can find this topic.<br>
<br>
<br>
Re your suggestion to use my own longjmp/setjmp - do you mean I should<br>
use the LLVM intrinsics? But would they not call the Windows API<br>
anyway?<br></blockquote><div><br></div></div><div dir="ltr"><div class="gmail_quote"><div>I'm not sure what your requirements are. Can you specify why do you need longjmp?</div><div><br></div><div>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:</div><div><br></div><div>setjmp, MSVC/C++</div><div>other code, LLVM MCJIT</div><div>longjmp, MSVC/C++</div><div><br></div><div>Your solutions are:</div><div><ol><li>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.</li><li>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. <br>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 <a href="http://lists.cs.uiuc.edu/pipermail/llvmdev/2015-February/081961.html">http://lists.cs.uiuc.edu/pipermail/llvmdev/2015-February/081961.html</a></li></ol></div></div></div><div dir="ltr"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
I am also wondering if mingw gcc compilers have the same issue.<br></blockquote><div><br></div><div>MinGW has its own implementation of setjmp/longjmp. Its longjmp do not do C++ stack unwinding of course. </div><div><br></div><div>- Paweł</div></div></div></div>