[Vm-dev] 64bits Pharo VM for windows

Ben Coman btc at openinworld.com
Fri May 19 00:39:46 UTC 2017


On Fri, May 19, 2017 at 12:10 AM, Eliot Miranda <eliot.miranda at gmail.com> wrote:
>
> Hi Ben,
>
>     see below...
>
> On Thu, May 18, 2017 at 7:59 AM, Ben Coman <btc at openinworld.com> wrote:
>>
>>
>> On Thu, Mar 23, 2017 at 7:06 PM, Ben Coman <btc at openinworld.com> wrote:
>> > Probably not related, but just some things that turned up while I was
>> > browsing around...
>> >
>> > gdb unknown target exception
>> > http://stackoverflow.com/questions/40923437/gdb-unknown-target-exception
>> >
>> > gdb Exception in SetThreadName(unsigned long, char const*) () from
>> > /usr/bin/cygwin1.dll
>> > https://www.mail-archive.com/cygwin@cygwin.com/msg149735.html
>> >
>> > cygwin gdb Program received signal ?, Unknown signal
>> > http://stackoverflow.com/questions/40652302/cygwin-gdb-program-received-signal-unknown-signal
>> >
>> > Quick reference to Implementation...
>> > https://github.com/Alexpux/Cygwin/blob/master/newlib/libc/include/setjmp.h
>> > https://github.com/Alexpux/Cygwin/blob/master/newlib/libc/machine/i386/setjmp.S
>> > https://github.com/Alexpux/Cygwin/blob/master/newlib/libc/machine/x86_64/setjmp.S
>> > https://github.com/Alexpux/Cygwin/blob/master/newlib/libc/include/machine/setjmp.h
>>
>> btw, here is a comparison of i386 versus x86_64 Cygwin longjmp...
>> https://www.diffchecker.com/iAMuXTMn
>>
>>
>> > 2015-07-21 Corinna Vinschen <corinna at vinschen.de>
>> > (setjmp): x86_64 only: Store tls stackptr in Frame now, store MXCSR
>> > and FPUCW registers in Spare, as MSVCRT does.
>> > (longjmp): x86_64 only: Restore tls stackptr from Frame now, restore
>> > MXCSR and FPUCW registers from Spare.
>> > 2015-06-27 Corinna Vinschen <corinna at vinschen.de>
>> > * exceptions.cc (_cygtls::call_signal_handler): Drop manipulating
>> > thread's ss_flags here. It's not safe against longjmp.
>> > https://github.com/Alexpux/Cygwin/blob/..../winsup/CVSChangeLogs.old/cygwin/ChangeLog-2015
>> >
>> >
>>
>> I've been trawling the web for more candidates.  This is a bit
>> scattershot and I'm not in a position to experiment on Windows right
>> now,
>> but maybe useful hints for someone...
>>
>> * "setjmp and longjmp (emu.c) and crashes when used in a 64bit windows
>> environment because setjmp sets the stack register value to 0x10.
>> Using __builtin_setjump avoids the problem because the stack register
>> doesn't get messed (doesn't seem to call setjmp3 function of the
>> C:\Windows\SysWOW64\msvcrt.dll library)."
>> https://sourceforge.net/p/mingw-w64/bugs/406/
>>
>> * "The problem turns out to be incorrect relocation by the internal
>> linker ... only applies to imported symbols."
>> Maybe why __builtin_setjump reported to work okay ??
>> https://github.com/golang/go/issues/13672
>>
>> * probably this doesn't apply to Cygwin non-C++ code. But maybe msvcrt
>> is written in C++ ?? ... "In portable code, when a non-local goto that
>> calls longjmp is executed, correct destruction of frame-based objects
>> might be unreliable."
>> https://msdn.microsoft.com/en-us/library/yz2ez4as.aspx
>>
>> * 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.
>> http://lists.llvm.org/pipermail/llvm-dev/2015-April/084889.html
>
>
> The above is why we see the crash.  And the fix is to avoid exception unwinding.  When the VM uses longjmp it is never in a position where foreign code exists between the longjmp and setjmp points and so there is never any need to unwind the stack.  The VM does not include exception handlers or unwind-protects in its code, at least not between the setjmp/longjmp pairs used to
>
> - return from machine code to the interpreter
> - return from evaluating a callback to the entry-point into the VM for that callback (thinkEntry)
>
> So the fix is merely to avoid stack unwinding in the version of setjmp/longjmp the VM uses for these two operations.
>
> One thing we could do is implement a setjmp/longjmp pair in the JIT and therefore possibly shave a few cycles off the process.  But for now the approach Nicolas is taking is a rational one.

Thanks for expanding on how this applied to us.
cheers -ben

>
>
>> * Perhaps we need to wrap exception handling around calls to functions
>> in the msvcrt.dll ???
>>   "Most functions that make use of the stack in 64-bit versions of
>> Windows must support exception handling even if they make no internal
>> use of such facilities."
>> https://www.tortall.net/projects/yasm/manual/html/objfmt-win64-exception.html
>>
>> * "This is a bug fix needed for 64 bit Windows. QEMU for Windows
>> currently gets the wrong definition for sigsetjmp. It uses stack
>> unwinding for longjmp which results in a crash when it is called from
>> generated code. (1 Mar 2016)"
>> https://lists.gnu.org/archive/html/qemu-devel/2016-03/msg00000.html
>>
>> * I'm not sure if I understand it properly, but this seems to imply
>> that that even pure-C (not C++) applications need to catch exceptions
>> of OS C++ library ?? .
>> http://ab-initio.mit.edu/octave-Faddeeva/gnulib/lib/msvc-inval.h
>>
>> * "The newer runtime libraries of MSVC no longer return error codes
>> from functions like printf(), close(), dup2(), _get_osfhandle(), when
>> you pass an invalid format string or invalid file descriptor."
>> https://lists.gnu.org/archive/html/bug-gnulib/2011-09/msg00239.html
>>
>> * " With MSVC runtime libraries with the "invalid parameter handler"
>> concept, Functions like fprintf(), dup2(), or close() crash when the
>> caller passes an invalid argument.  But POSIX wants error codes (such
>> as EINVAL or EBADF) instead."
>> http://ab-initio.mit.edu/octave-Faddeeva/gnulib/lib/msvc-inval.h
>>
>> * 'The try-except statement is a Microsoft extension to the C ... language"
>> https://msdn.microsoft.com/en-us/library/s58ftw19.aspx
>>
>> cheers -ben
>>
>> <snip>
>> >> Certainly look ok at the instruction that raised the exception.  Looks like the longjmp is trying to return to somewhere it shouldn't.  Also you've written "snip" at the hot end of the stack.  If that's not a typo, post all of the hot end of the stack.
>> >>
>> >> You could look at the returnToInterpreter jmpbuf after the setjmp that initializes it and become familiar with its contents.  Then check when the longjmp occurs that it is t corrupted and the frame that created it still exists on the stack.
>> <snip>
>
>
>
>
> --
> _,,,^..^,,,_
> best, Eliot
>


More information about the Vm-dev mailing list