64bits Pharo VM for windows

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
19 messages Options
Reply | Threaded
Open this post in threaded view
|

64bits Pharo VM for windows

Nicolas Cellier
 
Hi,
I've built a 64bits pharo.stack.spur VM for windows on my machine,
and I'm uploading the changes to opensmalltalk-vm in branch
build_pharo_win32_with_cygwin

If the appveyor job correctly succeed, I will emit a pull request.

The VM does not have the SqueakSSL plugin yet.

The 64bits squeak/pharo.cog.spur JIT for windows is still to come,
but I did not work on it for a few months...
One thing at a time.

Let's cross finger

Nicolas
Reply | Threaded
Open this post in threaded view
|

Re: 64bits Pharo VM for windows

Nicolas Cellier
 

2017-03-19 17:31 GMT+01:00 Nicolas Cellier <[hidden email]>:
Hi,
I've built a 64bits pharo.stack.spur VM for windows on my machine,
and I'm uploading the changes to opensmalltalk-vm in branch
build_pharo_win32_with_cygwin

If the appveyor job correctly succeed, I will emit a pull request.

The VM does not have the SqueakSSL plugin yet.

The 64bits squeak/pharo.cog.spur JIT for windows is still to come,
but I did not work on it for a few months...
One thing at a time.

Let's cross finger

Nicolas

Reply | Threaded
Open this post in threaded view
|

Re: 64bits Pharo VM for windows

Clément Béra
 
Thank you very much for doing Nicolas. It is very important for many Pharo users to use Pharo 64 bits on Windows.

What are the problems you have when trying to build the VM with the JIT that you don't have when building the stack VM ? Is it about API to make the memory executable, is it about calling conventions ?

On Sun, Mar 19, 2017 at 12:14 PM, Nicolas Cellier <[hidden email]> wrote:
 

2017-03-19 17:31 GMT+01:00 Nicolas Cellier <[hidden email]>:
Hi,
I've built a 64bits pharo.stack.spur VM for windows on my machine,
and I'm uploading the changes to opensmalltalk-vm in branch
build_pharo_win32_with_cygwin

If the appveyor job correctly succeed, I will emit a pull request.

The VM does not have the SqueakSSL plugin yet.

The 64bits squeak/pharo.cog.spur JIT for windows is still to come,
but I did not work on it for a few months...
One thing at a time.

Let's cross finger

Nicolas



Reply | Threaded
Open this post in threaded view
|

Re: 64bits Pharo VM for windows

Nicolas Cellier
 
Hi Clement,
it's been a while since I last tested, but in a few words:
- win64 use it's own ABI
- we have to assign the registers differently than sysV
- the experiments I did resulted in VM crashing early (before opening window)

Nicolas

2017-03-19 20:29 GMT+01:00 Clément Bera <[hidden email]>:
 
Thank you very much for doing Nicolas. It is very important for many Pharo users to use Pharo 64 bits on Windows.

What are the problems you have when trying to build the VM with the JIT that you don't have when building the stack VM ? Is it about API to make the memory executable, is it about calling conventions ?

On Sun, Mar 19, 2017 at 12:14 PM, Nicolas Cellier <[hidden email]> wrote:
 

2017-03-19 17:31 GMT+01:00 Nicolas Cellier <[hidden email]>:
Hi,
I've built a 64bits pharo.stack.spur VM for windows on my machine,
and I'm uploading the changes to opensmalltalk-vm in branch
build_pharo_win32_with_cygwin

If the appveyor job correctly succeed, I will emit a pull request.

The VM does not have the SqueakSSL plugin yet.

The 64bits squeak/pharo.cog.spur JIT for windows is still to come,
but I did not work on it for a few months...
One thing at a time.

Let's cross finger

Nicolas





Reply | Threaded
Open this post in threaded view
|

Re: 64bits Pharo VM for windows

Nicolas Cellier
 
It's necessary to hack the CogX64Compiler SysV class var initialization and generate a win64 specific cogitX64.c.


2017-03-19 20:34 GMT+01:00 Nicolas Cellier <[hidden email]>:
Hi Clement,
it's been a while since I last tested, but in a few words:
- win64 use it's own ABI
- we have to assign the registers differently than sysV
- the experiments I did resulted in VM crashing early (before opening window)

Nicolas

2017-03-19 20:29 GMT+01:00 Clément Bera <[hidden email]>:
 
Thank you very much for doing Nicolas. It is very important for many Pharo users to use Pharo 64 bits on Windows.

What are the problems you have when trying to build the VM with the JIT that you don't have when building the stack VM ? Is it about API to make the memory executable, is it about calling conventions ?

On Sun, Mar 19, 2017 at 12:14 PM, Nicolas Cellier <[hidden email]> wrote:
 

2017-03-19 17:31 GMT+01:00 Nicolas Cellier <[hidden email]>:
Hi,
I've built a 64bits pharo.stack.spur VM for windows on my machine,
and I'm uploading the changes to opensmalltalk-vm in branch
build_pharo_win32_with_cygwin

If the appveyor job correctly succeed, I will emit a pull request.

The VM does not have the SqueakSSL plugin yet.

The 64bits squeak/pharo.cog.spur JIT for windows is still to come,
but I did not work on it for a few months...
One thing at a time.

Let's cross finger

Nicolas






Reply | Threaded
Open this post in threaded view
|

Re: 64bits Pharo VM for windows

Nicolas Cellier
 
Thanks Eliot for pushing WIN64 ABI further!

So the failure is this one:

gdb: unknown target exception 0xc0000028 at 0x774c8078

Program received signal ?, Unknown signal.
0x00000000774c8078 in ntdll!RtlRaiseStatus () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll
(gdb) where
#0  0x00000000774c8078 in ntdll!RtlRaiseStatus () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll
#1  0x0000000077467eb6 in ntdll!TpAlpcRegisterCompletionList () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll
#2  0x000007fefe08e5a3 in msvcrt!longjmp () from /cygdrive/c/Windows/system32/msvcrt.dll
#3  0x0000000000419502 in ceReturnToInterpreter (anOop=176164968) at ../../spur64src/vm/gcc3x-cointerp.c:16504
#4  0x000000000a801086 in ?? ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)

I now suspect the jmp_buf alignment problem that I had to workaround in jpeg plugin:
It must be aligned on 16 bytes boundary in Win64, but sometimes the compiler fails to honour this requirement
See https://github.com/OpenSmalltalk/opensmalltalk-vm/pull/120


2017-03-19 21:03 GMT+01:00 Nicolas Cellier <[hidden email]>:
It's necessary to hack the CogX64Compiler SysV class var initialization and generate a win64 specific cogitX64.c.


2017-03-19 20:34 GMT+01:00 Nicolas Cellier <[hidden email]>:
Hi Clement,
it's been a while since I last tested, but in a few words:
- win64 use it's own ABI
- we have to assign the registers differently than sysV
- the experiments I did resulted in VM crashing early (before opening window)

Nicolas

2017-03-19 20:29 GMT+01:00 Clément Bera <[hidden email]>:
 
Thank you very much for doing Nicolas. It is very important for many Pharo users to use Pharo 64 bits on Windows.

What are the problems you have when trying to build the VM with the JIT that you don't have when building the stack VM ? Is it about API to make the memory executable, is it about calling conventions ?

On Sun, Mar 19, 2017 at 12:14 PM, Nicolas Cellier <[hidden email]> wrote:
 

2017-03-19 17:31 GMT+01:00 Nicolas Cellier <[hidden email]>:
Hi,
I've built a 64bits pharo.stack.spur VM for windows on my machine,
and I'm uploading the changes to opensmalltalk-vm in branch
build_pharo_win32_with_cygwin

If the appveyor job correctly succeed, I will emit a pull request.

The VM does not have the SqueakSSL plugin yet.

The 64bits squeak/pharo.cog.spur JIT for windows is still to come,
but I did not work on it for a few months...
One thing at a time.

Let's cross finger

Nicolas







Reply | Threaded
Open this post in threaded view
|

Re: 64bits Pharo VM for windows

Eliot Miranda-2
 
Hi Nicolas,

On Mon, Mar 20, 2017 at 3:45 PM, Nicolas Cellier <[hidden email]> wrote:
 
Thanks Eliot for pushing WIN64 ABI further!

So the failure is this one:

gdb: unknown target exception 0xc0000028 at 0x774c8078

Program received signal ?, Unknown signal.
0x00000000774c8078 in ntdll!RtlRaiseStatus () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll
(gdb) where
#0  0x00000000774c8078 in ntdll!RtlRaiseStatus () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll
#1  0x0000000077467eb6 in ntdll!TpAlpcRegisterCompletionList () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll
#2  0x000007fefe08e5a3 in msvcrt!longjmp () from /cygdrive/c/Windows/system32/msvcrt.dll
#3  0x0000000000419502 in ceReturnToInterpreter (anOop=176164968) at ../../spur64src/vm/gcc3x-cointerp.c:16504
#4  0x000000000a801086 in ?? ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)

I now suspect the jmp_buf alignment problem that I had to workaround in jpeg plugin:
It must be aligned on 16 bytes boundary in Win64, but sometimes the compiler fails to honour this requirement
See https://github.com/OpenSmalltalk/opensmalltalk-vm/pull/120

Hmph.  So the stack /should/ be aligned on a 16-byte boundary and hence the compiler /should/ be able to maintain the invariant (see platforms/Cross/vm/sqCogStackAlignment.h; in fact on Mac OS X the alignment is 32 bytes).
 
Let me suggest that you add the following to the preamble:

#if WIN64
# define sigsetjmp(jb,ssmf) (assert(((int)jb & 15) == 0, setjmp(jb))
# define siglongjmp(jb,v) (assert(((int)jb & 15) == 0, longjmp(jb,v))
#elif WIN32
...

and make sure there's a self assertCStackWellAligned send in ceReturnToInterpreter.





2017-03-19 21:03 GMT+01:00 Nicolas Cellier <[hidden email]>:
It's necessary to hack the CogX64Compiler SysV class var initialization and generate a win64 specific cogitX64.c.


2017-03-19 20:34 GMT+01:00 Nicolas Cellier <[hidden email]>:
Hi Clement,
it's been a while since I last tested, but in a few words:
- win64 use it's own ABI
- we have to assign the registers differently than sysV
- the experiments I did resulted in VM crashing early (before opening window)

Nicolas

2017-03-19 20:29 GMT+01:00 Clément Bera <[hidden email]>:
 
Thank you very much for doing Nicolas. It is very important for many Pharo users to use Pharo 64 bits on Windows.

What are the problems you have when trying to build the VM with the JIT that you don't have when building the stack VM ? Is it about API to make the memory executable, is it about calling conventions ?

On Sun, Mar 19, 2017 at 12:14 PM, Nicolas Cellier <[hidden email]> wrote:
 

2017-03-19 17:31 GMT+01:00 Nicolas Cellier <[hidden email]>:
Hi,
I've built a 64bits pharo.stack.spur VM for windows on my machine,
and I'm uploading the changes to opensmalltalk-vm in branch
build_pharo_win32_with_cygwin

If the appveyor job correctly succeed, I will emit a pull request.

The VM does not have the SqueakSSL plugin yet.

The 64bits squeak/pharo.cog.spur JIT for windows is still to come,
but I did not work on it for a few months...
One thing at a time.

Let's cross finger

Nicolas











--
_,,,^..^,,,_
best, Eliot
Reply | Threaded
Open this post in threaded view
|

Re: 64bits Pharo VM for windows

Eliot Miranda-2
 
Hi Nicolas,

On Mon, Mar 20, 2017 at 5:56 PM, Eliot Miranda <[hidden email]> wrote:
Hi Nicolas,

On Mon, Mar 20, 2017 at 3:45 PM, Nicolas Cellier <[hidden email]> wrote:
 
Thanks Eliot for pushing WIN64 ABI further!

So the failure is this one:

gdb: unknown target exception 0xc0000028 at 0x774c8078

Program received signal ?, Unknown signal.
0x00000000774c8078 in ntdll!RtlRaiseStatus () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll
(gdb) where
#0  0x00000000774c8078 in ntdll!RtlRaiseStatus () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll
#1  0x0000000077467eb6 in ntdll!TpAlpcRegisterCompletionList () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll
#2  0x000007fefe08e5a3 in msvcrt!longjmp () from /cygdrive/c/Windows/system32/msvcrt.dll
#3  0x0000000000419502 in ceReturnToInterpreter (anOop=176164968) at ../../spur64src/vm/gcc3x-cointerp.c:16504
#4  0x000000000a801086 in ?? ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)

I now suspect the jmp_buf alignment problem that I had to workaround in jpeg plugin:
It must be aligned on 16 bytes boundary in Win64, but sometimes the compiler fails to honour this requirement
See https://github.com/OpenSmalltalk/opensmalltalk-vm/pull/120

Hmph.  So the stack /should/ be aligned on a 16-byte boundary and hence the compiler /should/ be able to maintain the invariant (see platforms/Cross/vm/sqCogStackAlignment.h; in fact on Mac OS X the alignment is 32 bytes).
 
Let me suggest that you add the following to the preamble:

#if WIN64
# define sigsetjmp(jb,ssmf) (assert(((int)jb & 15) == 0, setjmp(jb))
# define siglongjmp(jb,v) (assert(((int)jb & 15) == 0, longjmp(jb,v))
#elif WIN32
...

and make sure there's a self assertCStackWellAligned send in ceReturnToInterpreter.

Hmmm.  I expect we need code in the ceReturnToInterpreterTrampoline that establishes the stack alignment requirement.  ceReturnToInterpreter: would be called from machine code where there is only 8 byte alignment on x64 (& 4 byte alignment on 32-bit VMs).  If you like I can try and implement this tomorrow.


2017-03-19 21:03 GMT+01:00 Nicolas Cellier <[hidden email]>:
It's necessary to hack the CogX64Compiler SysV class var initialization and generate a win64 specific cogitX64.c.


2017-03-19 20:34 GMT+01:00 Nicolas Cellier <[hidden email]>:
Hi Clement,
it's been a while since I last tested, but in a few words:
- win64 use it's own ABI
- we have to assign the registers differently than sysV
- the experiments I did resulted in VM crashing early (before opening window)

Nicolas

2017-03-19 20:29 GMT+01:00 Clément Bera <[hidden email]>:
 
Thank you very much for doing Nicolas. It is very important for many Pharo users to use Pharo 64 bits on Windows.

What are the problems you have when trying to build the VM with the JIT that you don't have when building the stack VM ? Is it about API to make the memory executable, is it about calling conventions ?

On Sun, Mar 19, 2017 at 12:14 PM, Nicolas Cellier <[hidden email]> wrote:
 

2017-03-19 17:31 GMT+01:00 Nicolas Cellier <[hidden email]>:
Hi,
I've built a 64bits pharo.stack.spur VM for windows on my machine,
and I'm uploading the changes to opensmalltalk-vm in branch
build_pharo_win32_with_cygwin

If the appveyor job correctly succeed, I will emit a pull request.

The VM does not have the SqueakSSL plugin yet.

The 64bits squeak/pharo.cog.spur JIT for windows is still to come,
but I did not work on it for a few months...
One thing at a time.

Let's cross finger

Nicolas











--
_,,,^..^,,,_
best, Eliot



--
_,,,^..^,,,_
best, Eliot
Reply | Threaded
Open this post in threaded view
|

Re: 64bits Pharo VM for windows

Eliot Miranda-2
 


On Mon, Mar 20, 2017 at 6:01 PM, Eliot Miranda <[hidden email]> wrote:
Hi Nicolas,

On Mon, Mar 20, 2017 at 5:56 PM, Eliot Miranda <[hidden email]> wrote:
Hi Nicolas,

On Mon, Mar 20, 2017 at 3:45 PM, Nicolas Cellier <[hidden email]> wrote:
 
Thanks Eliot for pushing WIN64 ABI further!

So the failure is this one:

gdb: unknown target exception 0xc0000028 at 0x774c8078

Program received signal ?, Unknown signal.
0x00000000774c8078 in ntdll!RtlRaiseStatus () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll
(gdb) where
#0  0x00000000774c8078 in ntdll!RtlRaiseStatus () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll
#1  0x0000000077467eb6 in ntdll!TpAlpcRegisterCompletionList () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll
#2  0x000007fefe08e5a3 in msvcrt!longjmp () from /cygdrive/c/Windows/system32/msvcrt.dll
#3  0x0000000000419502 in ceReturnToInterpreter (anOop=176164968) at ../../spur64src/vm/gcc3x-cointerp.c:16504
#4  0x000000000a801086 in ?? ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)

I now suspect the jmp_buf alignment problem that I had to workaround in jpeg plugin:
It must be aligned on 16 bytes boundary in Win64, but sometimes the compiler fails to honour this requirement
See https://github.com/OpenSmalltalk/opensmalltalk-vm/pull/120

Hmph.  So the stack /should/ be aligned on a 16-byte boundary and hence the compiler /should/ be able to maintain the invariant (see platforms/Cross/vm/sqCogStackAlignment.h; in fact on Mac OS X the alignment is 32 bytes).
 
Let me suggest that you add the following to the preamble:

#if WIN64
# define sigsetjmp(jb,ssmf) (assert(((int)jb & 15) == 0, setjmp(jb))
# define siglongjmp(jb,v) (assert(((int)jb & 15) == 0, longjmp(jb,v))
#elif WIN32
...

and make sure there's a self assertCStackWellAligned send in ceReturnToInterpreter.

Hmmm.  I expect we need code in the ceReturnToInterpreterTrampoline that establishes the stack alignment requirement.  ceReturnToInterpreter: would be called from machine code where there is only 8 byte alignment on x64 (& 4 byte alignment on 32-bit VMs).  If you like I can try and implement this tomorrow.

 Looking at the code, that's not necessary.  The trampoline still switches to the C stack, which should be correctly aligned.  So yes, definitely add the "self assertCStackWellAligned" to both ceReturnToInterpreter: and ceBaseFrameReturn:.  It looks like the issue is whether the returnToInterpreter jmpbuf is correctly aligned.


2017-03-19 21:03 GMT+01:00 Nicolas Cellier <[hidden email]>:
It's necessary to hack the CogX64Compiler SysV class var initialization and generate a win64 specific cogitX64.c.


2017-03-19 20:34 GMT+01:00 Nicolas Cellier <[hidden email]>:
Hi Clement,
it's been a while since I last tested, but in a few words:
- win64 use it's own ABI
- we have to assign the registers differently than sysV
- the experiments I did resulted in VM crashing early (before opening window)

Nicolas

2017-03-19 20:29 GMT+01:00 Clément Bera <[hidden email]>:
 
Thank you very much for doing Nicolas. It is very important for many Pharo users to use Pharo 64 bits on Windows.

What are the problems you have when trying to build the VM with the JIT that you don't have when building the stack VM ? Is it about API to make the memory executable, is it about calling conventions ?

On Sun, Mar 19, 2017 at 12:14 PM, Nicolas Cellier <[hidden email]> wrote:
 

2017-03-19 17:31 GMT+01:00 Nicolas Cellier <[hidden email]>:
Hi,
I've built a 64bits pharo.stack.spur VM for windows on my machine,
and I'm uploading the changes to opensmalltalk-vm in branch
build_pharo_win32_with_cygwin

If the appveyor job correctly succeed, I will emit a pull request.

The VM does not have the SqueakSSL plugin yet.

The 64bits squeak/pharo.cog.spur JIT for windows is still to come,
but I did not work on it for a few months...
One thing at a time.

Let's cross finger

Nicolas











--
_,,,^..^,,,_
best, Eliot



--
_,,,^..^,,,_
best, Eliot



--
_,,,^..^,,,_
best, Eliot
Reply | Threaded
Open this post in threaded view
|

Re: 64bits Pharo VM for windows

Nicolas Cellier
 
Hi Eliot,
I'll try the assert if I can find a time slot today, otherwise this evening.
I could also have printed the jump_buf address in gdb, but it was too late yesterday ;)


2017-03-21 2:19 GMT+01:00 Eliot Miranda <[hidden email]>:
 


On Mon, Mar 20, 2017 at 6:01 PM, Eliot Miranda <[hidden email]> wrote:
Hi Nicolas,

On Mon, Mar 20, 2017 at 5:56 PM, Eliot Miranda <[hidden email]> wrote:
Hi Nicolas,

On Mon, Mar 20, 2017 at 3:45 PM, Nicolas Cellier <[hidden email]> wrote:
 
Thanks Eliot for pushing WIN64 ABI further!

So the failure is this one:

gdb: unknown target exception 0xc0000028 at 0x774c8078

Program received signal ?, Unknown signal.
0x00000000774c8078 in ntdll!RtlRaiseStatus () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll
(gdb) where
#0  0x00000000774c8078 in ntdll!RtlRaiseStatus () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll
#1  0x0000000077467eb6 in ntdll!TpAlpcRegisterCompletionList () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll
#2  0x000007fefe08e5a3 in msvcrt!longjmp () from /cygdrive/c/Windows/system32/msvcrt.dll
#3  0x0000000000419502 in ceReturnToInterpreter (anOop=176164968) at ../../spur64src/vm/gcc3x-cointerp.c:16504
#4  0x000000000a801086 in ?? ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)

I now suspect the jmp_buf alignment problem that I had to workaround in jpeg plugin:
It must be aligned on 16 bytes boundary in Win64, but sometimes the compiler fails to honour this requirement
See https://github.com/OpenSmalltalk/opensmalltalk-vm/pull/120

Hmph.  So the stack /should/ be aligned on a 16-byte boundary and hence the compiler /should/ be able to maintain the invariant (see platforms/Cross/vm/sqCogStackAlignment.h; in fact on Mac OS X the alignment is 32 bytes).
 
Let me suggest that you add the following to the preamble:

#if WIN64
# define sigsetjmp(jb,ssmf) (assert(((int)jb & 15) == 0, setjmp(jb))
# define siglongjmp(jb,v) (assert(((int)jb & 15) == 0, longjmp(jb,v))
#elif WIN32
...

and make sure there's a self assertCStackWellAligned send in ceReturnToInterpreter.

Hmmm.  I expect we need code in the ceReturnToInterpreterTrampoline that establishes the stack alignment requirement.  ceReturnToInterpreter: would be called from machine code where there is only 8 byte alignment on x64 (& 4 byte alignment on 32-bit VMs).  If you like I can try and implement this tomorrow.

 Looking at the code, that's not necessary.  The trampoline still switches to the C stack, which should be correctly aligned.  So yes, definitely add the "self assertCStackWellAligned" to both ceReturnToInterpreter: and ceBaseFrameReturn:.  It looks like the issue is whether the returnToInterpreter jmpbuf is correctly aligned.


2017-03-19 21:03 GMT+01:00 Nicolas Cellier <[hidden email]>:
It's necessary to hack the CogX64Compiler SysV class var initialization and generate a win64 specific cogitX64.c.


2017-03-19 20:34 GMT+01:00 Nicolas Cellier <[hidden email]>:
Hi Clement,
it's been a while since I last tested, but in a few words:
- win64 use it's own ABI
- we have to assign the registers differently than sysV
- the experiments I did resulted in VM crashing early (before opening window)

Nicolas

2017-03-19 20:29 GMT+01:00 Clément Bera <[hidden email]>:
 
Thank you very much for doing Nicolas. It is very important for many Pharo users to use Pharo 64 bits on Windows.

What are the problems you have when trying to build the VM with the JIT that you don't have when building the stack VM ? Is it about API to make the memory executable, is it about calling conventions ?

On Sun, Mar 19, 2017 at 12:14 PM, Nicolas Cellier <[hidden email]> wrote:
 

2017-03-19 17:31 GMT+01:00 Nicolas Cellier <[hidden email]>:
Hi,
I've built a 64bits pharo.stack.spur VM for windows on my machine,
and I'm uploading the changes to opensmalltalk-vm in branch
build_pharo_win32_with_cygwin

If the appveyor job correctly succeed, I will emit a pull request.

The VM does not have the SqueakSSL plugin yet.

The 64bits squeak/pharo.cog.spur JIT for windows is still to come,
but I did not work on it for a few months...
One thing at a time.

Let's cross finger

Nicolas











--
_,,,^..^,,,_
best, Eliot



--
_,,,^..^,,,_
best, Eliot



--
_,,,^..^,,,_
best, Eliot


Reply | Threaded
Open this post in threaded view
|

Re: 64bits Pharo VM for windows

Nicolas Cellier
 


2017-03-21 7:48 GMT+01:00 Nicolas Cellier <[hidden email]>:
Hi Eliot,
I'll try the assert if I can find a time slot today, otherwise this evening.
I could also have printed the jump_buf address in gdb, but it was too late yesterday ;)


2017-03-21 2:19 GMT+01:00 Eliot Miranda <[hidden email]>:
 


On Mon, Mar 20, 2017 at 6:01 PM, Eliot Miranda <[hidden email]> wrote:
Hi Nicolas,

On Mon, Mar 20, 2017 at 5:56 PM, Eliot Miranda <[hidden email]> wrote:
Hi Nicolas,

On Mon, Mar 20, 2017 at 3:45 PM, Nicolas Cellier <[hidden email]> wrote:
 
Thanks Eliot for pushing WIN64 ABI further!

So the failure is this one:

gdb: unknown target exception 0xc0000028 at 0x774c8078

Program received signal ?, Unknown signal.
0x00000000774c8078 in ntdll!RtlRaiseStatus () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll
(gdb) where
#0  0x00000000774c8078 in ntdll!RtlRaiseStatus () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll
#1  0x0000000077467eb6 in ntdll!TpAlpcRegisterCompletionList () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll
#2  0x000007fefe08e5a3 in msvcrt!longjmp () from /cygdrive/c/Windows/system32/msvcrt.dll
#3  0x0000000000419502 in ceReturnToInterpreter (anOop=176164968) at ../../spur64src/vm/gcc3x-cointerp.c:16504
#4  0x000000000a801086 in ?? ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)

I now suspect the jmp_buf alignment problem that I had to workaround in jpeg plugin:
It must be aligned on 16 bytes boundary in Win64, but sometimes the compiler fails to honour this requirement
See https://github.com/OpenSmalltalk/opensmalltalk-vm/pull/120

Hmph.  So the stack /should/ be aligned on a 16-byte boundary and hence the compiler /should/ be able to maintain the invariant (see platforms/Cross/vm/sqCogStackAlignment.h; in fact on Mac OS X the alignment is 32 bytes).
 
Let me suggest that you add the following to the preamble:

#if WIN64
# define sigsetjmp(jb,ssmf) (assert(((int)jb & 15) == 0, setjmp(jb))
# define siglongjmp(jb,v) (assert(((int)jb & 15) == 0, longjmp(jb,v))
#elif WIN32
...

and make sure there's a self assertCStackWellAligned send in ceReturnToInterpreter.

Hmmm.  I expect we need code in the ceReturnToInterpreterTrampoline that establishes the stack alignment requirement.  ceReturnToInterpreter: would be called from machine code where there is only 8 byte alignment on x64 (& 4 byte alignment on 32-bit VMs).  If you like I can try and implement this tomorrow.

 Looking at the code, that's not necessary.  The trampoline still switches to the C stack, which should be correctly aligned.  So yes, definitely add the "self assertCStackWellAligned" to both ceReturnToInterpreter: and ceBaseFrameReturn:.  It looks like the issue is whether the returnToInterpreter jmpbuf is correctly aligned.



The STACK_ALIGN_BYTES is 16 in good agreement with WIN64 ABI and assertCStackWellAligned() do succeed in ceReturnToInterpreter...

So, I added the assertion on setjmp and longjmp, but they do not fail.
The jmp_buf reenterInterpreter is correctly aligned on 16 bytes boundary.
There is a declaration like this in setjmp.h
 typedef _CRT_ALIGN(16) struct _SETJMP_FLOAT128
So local and global jmp_buf variables are allways well aligned by the C compiler(s)

The jpeg problem was caused by putting the jmp_buf into a structure.
Apparently, gcc and clang fail to correctly handle that case
(they should first align the whole struct on 16 bytes then align the offset of the jmp_buf member).

There are other cases that will be problematic in Win64 exactly like the jpeg case, for example I see:
siglongjmp((vmCallbackContext->trampoline)... in returnAsThroughCallbackContext
longjmp(GIV(jmpBuf)[GIV(jmpDepth)]...in callbackLeave (only #if SQ_USE_GLOBAL_STRUCT)

We should memcpy these to a local jmp_buf for WIN64 compatibility.

But the VM failed before ever reaching one of these callbacks (we should have none in Squeak by default)

So, wrong guess from my side for the moment, seeing longjmp on the call stack raised that false alarm.

 

2017-03-19 21:03 GMT+01:00 Nicolas Cellier <[hidden email]>:
It's necessary to hack the CogX64Compiler SysV class var initialization and generate a win64 specific cogitX64.c.


2017-03-19 20:34 GMT+01:00 Nicolas Cellier <[hidden email]>:
Hi Clement,
it's been a while since I last tested, but in a few words:
- win64 use it's own ABI
- we have to assign the registers differently than sysV
- the experiments I did resulted in VM crashing early (before opening window)

Nicolas

2017-03-19 20:29 GMT+01:00 Clément Bera <[hidden email]>:
 
Thank you very much for doing Nicolas. It is very important for many Pharo users to use Pharo 64 bits on Windows.

What are the problems you have when trying to build the VM with the JIT that you don't have when building the stack VM ? Is it about API to make the memory executable, is it about calling conventions ?

On Sun, Mar 19, 2017 at 12:14 PM, Nicolas Cellier <[hidden email]> wrote:
 

2017-03-19 17:31 GMT+01:00 Nicolas Cellier <[hidden email]>:
Hi,
I've built a 64bits pharo.stack.spur VM for windows on my machine,
and I'm uploading the changes to opensmalltalk-vm in branch
build_pharo_win32_with_cygwin

If the appveyor job correctly succeed, I will emit a pull request.

The VM does not have the SqueakSSL plugin yet.

The 64bits squeak/pharo.cog.spur JIT for windows is still to come,
but I did not work on it for a few months...
One thing at a time.

Let's cross finger

Nicolas











--
_,,,^..^,,,_
best, Eliot



--
_,,,^..^,,,_
best, Eliot



--
_,,,^..^,,,_
best, Eliot



Reply | Threaded
Open this post in threaded view
|

Re: 64bits Pharo VM for windows

Nicolas Cellier
 
Gah, stupid me, I didn't realized that the vm was compiled for SysV...
I need to define -DWIN64ABI somewhere...

2017-03-21 22:18 GMT+01:00 Nicolas Cellier <[hidden email]>:


2017-03-21 7:48 GMT+01:00 Nicolas Cellier <[hidden email]>:
Hi Eliot,
I'll try the assert if I can find a time slot today, otherwise this evening.
I could also have printed the jump_buf address in gdb, but it was too late yesterday ;)


2017-03-21 2:19 GMT+01:00 Eliot Miranda <[hidden email]>:
 


On Mon, Mar 20, 2017 at 6:01 PM, Eliot Miranda <[hidden email]> wrote:
Hi Nicolas,

On Mon, Mar 20, 2017 at 5:56 PM, Eliot Miranda <[hidden email]> wrote:
Hi Nicolas,

On Mon, Mar 20, 2017 at 3:45 PM, Nicolas Cellier <[hidden email]> wrote:
 
Thanks Eliot for pushing WIN64 ABI further!

So the failure is this one:

gdb: unknown target exception 0xc0000028 at 0x774c8078

Program received signal ?, Unknown signal.
0x00000000774c8078 in ntdll!RtlRaiseStatus () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll
(gdb) where
#0  0x00000000774c8078 in ntdll!RtlRaiseStatus () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll
#1  0x0000000077467eb6 in ntdll!TpAlpcRegisterCompletionList () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll
#2  0x000007fefe08e5a3 in msvcrt!longjmp () from /cygdrive/c/Windows/system32/msvcrt.dll
#3  0x0000000000419502 in ceReturnToInterpreter (anOop=176164968) at ../../spur64src/vm/gcc3x-cointerp.c:16504
#4  0x000000000a801086 in ?? ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)

I now suspect the jmp_buf alignment problem that I had to workaround in jpeg plugin:
It must be aligned on 16 bytes boundary in Win64, but sometimes the compiler fails to honour this requirement
See https://github.com/OpenSmalltalk/opensmalltalk-vm/pull/120

Hmph.  So the stack /should/ be aligned on a 16-byte boundary and hence the compiler /should/ be able to maintain the invariant (see platforms/Cross/vm/sqCogStackAlignment.h; in fact on Mac OS X the alignment is 32 bytes).
 
Let me suggest that you add the following to the preamble:

#if WIN64
# define sigsetjmp(jb,ssmf) (assert(((int)jb & 15) == 0, setjmp(jb))
# define siglongjmp(jb,v) (assert(((int)jb & 15) == 0, longjmp(jb,v))
#elif WIN32
...

and make sure there's a self assertCStackWellAligned send in ceReturnToInterpreter.

Hmmm.  I expect we need code in the ceReturnToInterpreterTrampoline that establishes the stack alignment requirement.  ceReturnToInterpreter: would be called from machine code where there is only 8 byte alignment on x64 (& 4 byte alignment on 32-bit VMs).  If you like I can try and implement this tomorrow.

 Looking at the code, that's not necessary.  The trampoline still switches to the C stack, which should be correctly aligned.  So yes, definitely add the "self assertCStackWellAligned" to both ceReturnToInterpreter: and ceBaseFrameReturn:.  It looks like the issue is whether the returnToInterpreter jmpbuf is correctly aligned.



The STACK_ALIGN_BYTES is 16 in good agreement with WIN64 ABI and assertCStackWellAligned() do succeed in ceReturnToInterpreter...

So, I added the assertion on setjmp and longjmp, but they do not fail.
The jmp_buf reenterInterpreter is correctly aligned on 16 bytes boundary.
There is a declaration like this in setjmp.h
 typedef _CRT_ALIGN(16) struct _SETJMP_FLOAT128
So local and global jmp_buf variables are allways well aligned by the C compiler(s)

The jpeg problem was caused by putting the jmp_buf into a structure.
Apparently, gcc and clang fail to correctly handle that case
(they should first align the whole struct on 16 bytes then align the offset of the jmp_buf member).

There are other cases that will be problematic in Win64 exactly like the jpeg case, for example I see:
siglongjmp((vmCallbackContext->trampoline)... in returnAsThroughCallbackContext
longjmp(GIV(jmpBuf)[GIV(jmpDepth)]...in callbackLeave (only #if SQ_USE_GLOBAL_STRUCT)

We should memcpy these to a local jmp_buf for WIN64 compatibility.

But the VM failed before ever reaching one of these callbacks (we should have none in Squeak by default)

So, wrong guess from my side for the moment, seeing longjmp on the call stack raised that false alarm.

 

2017-03-19 21:03 GMT+01:00 Nicolas Cellier <[hidden email]>:
It's necessary to hack the CogX64Compiler SysV class var initialization and generate a win64 specific cogitX64.c.


2017-03-19 20:34 GMT+01:00 Nicolas Cellier <[hidden email]>:
Hi Clement,
it's been a while since I last tested, but in a few words:
- win64 use it's own ABI
- we have to assign the registers differently than sysV
- the experiments I did resulted in VM crashing early (before opening window)

Nicolas

2017-03-19 20:29 GMT+01:00 Clément Bera <[hidden email]>:
 
Thank you very much for doing Nicolas. It is very important for many Pharo users to use Pharo 64 bits on Windows.

What are the problems you have when trying to build the VM with the JIT that you don't have when building the stack VM ? Is it about API to make the memory executable, is it about calling conventions ?

On Sun, Mar 19, 2017 at 12:14 PM, Nicolas Cellier <[hidden email]> wrote:
 

2017-03-19 17:31 GMT+01:00 Nicolas Cellier <[hidden email]>:
Hi,
I've built a 64bits pharo.stack.spur VM for windows on my machine,
and I'm uploading the changes to opensmalltalk-vm in branch
build_pharo_win32_with_cygwin

If the appveyor job correctly succeed, I will emit a pull request.

The VM does not have the SqueakSSL plugin yet.

The 64bits squeak/pharo.cog.spur JIT for windows is still to come,
but I did not work on it for a few months...
One thing at a time.

Let's cross finger

Nicolas











--
_,,,^..^,,,_
best, Eliot



--
_,,,^..^,,,_
best, Eliot



--
_,,,^..^,,,_
best, Eliot




Reply | Threaded
Open this post in threaded view
|

Re: 64bits Pharo VM for windows

Nicolas Cellier
 
Now the failure is:

gdb: unknown target exception 0xc0000028 at 0x76f38078

Program received signal ?, Unknown signal.
0x0000000076f38078 in ntdll!RtlRaiseStatus () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll

(gdb) where
#0  0x0000000076f38078 in ntdll!RtlRaiseStatus () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll
#1  0x0000000076ed7eb6 in ntdll!TpAlpcRegisterCompletionList () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll
#2  0x000007fefeb7e5a3 in msvcrt!longjmp () from /cygdrive/c/Windows/system32/msvcrt.dll
#3  0x00000000004314f9 in returnToExecutivepostContextSwitch (inInterpreter=0, switchedContext=1)
    at ../../spur64src/vm/gcc3x-cointerp.c:22130
#4  0x000000000043a110 in activateNewMethod () at ../../spur64src/vm/gcc3x-cointerp.c:15045
#5  0x000000000043c6e2 in interpretMethodFromMachineCode () at ../../spur64src/vm/gcc3x-cointerp.c:19204
#6  0x0000000000442e19 in ceSendsupertonumArgs (selector=204444792, superNormalBar=0, rcvr=206540520, numArgs=0)
    at ../../spur64src/vm/gcc3x-cointerp.c:17228
#7  0x000000000b7000ba in ?? ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)

(gdb) up
#1  0x0000000076ed7eb6 in ntdll!TpAlpcRegisterCompletionList () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll
(gdb) up
#2  0x000007fefeb7e5a3 in msvcrt!longjmp () from /cygdrive/c/Windows/system32/msvcrt.dll
(gdb) up
#3  0x00000000004314f9 in returnToExecutivepostContextSwitch (inInterpreter=0, switchedContext=1)
    at ../../spur64src/vm/gcc3x-cointerp.c:22130
22130                   siglongjmp(reenterInterpreter, ReturnToInterpreter);

(gdb) call printCallStack()
... snip...
          0xf0b138 I Set class(HashedCollection class)>new 0xc4f8ee8: a(n) Set class
          0xf0b168 M FFICallbackThunk class>startUp: 0xdb6b718: a(n) FFICallbackThunk class
          0xf0b1c0 M [] in SmalltalkImage>send:toClassesNamedIn:with: 0xc553d18: a(n) SmalltalkImage
          0xf0b210 I OrderedCollection>do: 0xc8a81d8: a(n) OrderedCollection
          0xf0b260 I SmalltalkImage>send:toClassesNamedIn:with: 0xc553d18: a(n) SmalltalkImage
          0xf0b2b8 I SmalltalkImage>processStartUpList: 0xc553d18: a(n) SmalltalkImage
          0xf0b310 I SmalltalkImage>snapshot:andQuit:withExitCode:embedded: 0xc553d18: a(n) SmalltalkImage
         0xd1187b0 s SmalltalkImage>snapshot:andQuit:embedded:
         0xc79ee20 s SmalltalkImage>snapshot:andQuit:
         0xdc6c6b8 s TheWorldMenu>saveAndQuit
         0xdc6eb20 s TheWorldMenu>doMenuItem:with:
         0xdc6ef98 s [] in MenuItemMorph>invokeWithEvent:
         0xdc6f200 s BlockClosure>ensure:
         0xdc6f2b8 s CursorWithMask(Cursor)>showWhile:
         0xdc6f370 s MenuItemMorph>invokeWithEvent:
...snip...

(gdb) call longPrintOop(aMethodObj)

0x0d781f10:  70/112 d1/209 22/34  e0/224 7c/124 ba/186 31/49  86/134
0x0d781f18:  fe/254
         0xd781ed8: a(n) CompiledMethod (0x468=>0xc4f8168) format 0x1f nbytes 57 hdr8 ..... hash 0x0
 0               0x29 5(0x5) nLits 5 nArgs 0 nTemps 0
 1          0xc32c900 #initialize:
 2          0xc2fa9a8 #basicNew
 3               0x29 5(0x5)
 4          0xc2f9478 #new
 5          0xd759cf0 a(n) Association

This indeed look like HashedCollection class>>new
49 <70> self
50 <D1> send: basicNew
51 <22> pushConstant: 5
52 <E0> send: initialize:
53 <7C> returnTop

So that's the status of win64 cog currently...
I'll stop here for tonight.
Eliot, any clue what to look at?

2017-03-22 0:47 GMT+01:00 Nicolas Cellier <[hidden email]>:
Gah, stupid me, I didn't realized that the vm was compiled for SysV...
I need to define -DWIN64ABI somewhere...

2017-03-21 22:18 GMT+01:00 Nicolas Cellier <[hidden email]>:


2017-03-21 7:48 GMT+01:00 Nicolas Cellier <[hidden email]>:
Hi Eliot,
I'll try the assert if I can find a time slot today, otherwise this evening.
I could also have printed the jump_buf address in gdb, but it was too late yesterday ;)


2017-03-21 2:19 GMT+01:00 Eliot Miranda <[hidden email]>:
 


On Mon, Mar 20, 2017 at 6:01 PM, Eliot Miranda <[hidden email]> wrote:
Hi Nicolas,

On Mon, Mar 20, 2017 at 5:56 PM, Eliot Miranda <[hidden email]> wrote:
Hi Nicolas,

On Mon, Mar 20, 2017 at 3:45 PM, Nicolas Cellier <[hidden email]> wrote:
 
Thanks Eliot for pushing WIN64 ABI further!

So the failure is this one:

gdb: unknown target exception 0xc0000028 at 0x774c8078

Program received signal ?, Unknown signal.
0x00000000774c8078 in ntdll!RtlRaiseStatus () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll
(gdb) where
#0  0x00000000774c8078 in ntdll!RtlRaiseStatus () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll
#1  0x0000000077467eb6 in ntdll!TpAlpcRegisterCompletionList () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll
#2  0x000007fefe08e5a3 in msvcrt!longjmp () from /cygdrive/c/Windows/system32/msvcrt.dll
#3  0x0000000000419502 in ceReturnToInterpreter (anOop=176164968) at ../../spur64src/vm/gcc3x-cointerp.c:16504
#4  0x000000000a801086 in ?? ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)

I now suspect the jmp_buf alignment problem that I had to workaround in jpeg plugin:
It must be aligned on 16 bytes boundary in Win64, but sometimes the compiler fails to honour this requirement
See https://github.com/OpenSmalltalk/opensmalltalk-vm/pull/120

Hmph.  So the stack /should/ be aligned on a 16-byte boundary and hence the compiler /should/ be able to maintain the invariant (see platforms/Cross/vm/sqCogStackAlignment.h; in fact on Mac OS X the alignment is 32 bytes).
 
Let me suggest that you add the following to the preamble:

#if WIN64
# define sigsetjmp(jb,ssmf) (assert(((int)jb & 15) == 0, setjmp(jb))
# define siglongjmp(jb,v) (assert(((int)jb & 15) == 0, longjmp(jb,v))
#elif WIN32
...

and make sure there's a self assertCStackWellAligned send in ceReturnToInterpreter.

Hmmm.  I expect we need code in the ceReturnToInterpreterTrampoline that establishes the stack alignment requirement.  ceReturnToInterpreter: would be called from machine code where there is only 8 byte alignment on x64 (& 4 byte alignment on 32-bit VMs).  If you like I can try and implement this tomorrow.

 Looking at the code, that's not necessary.  The trampoline still switches to the C stack, which should be correctly aligned.  So yes, definitely add the "self assertCStackWellAligned" to both ceReturnToInterpreter: and ceBaseFrameReturn:.  It looks like the issue is whether the returnToInterpreter jmpbuf is correctly aligned.



The STACK_ALIGN_BYTES is 16 in good agreement with WIN64 ABI and assertCStackWellAligned() do succeed in ceReturnToInterpreter...

So, I added the assertion on setjmp and longjmp, but they do not fail.
The jmp_buf reenterInterpreter is correctly aligned on 16 bytes boundary.
There is a declaration like this in setjmp.h
 typedef _CRT_ALIGN(16) struct _SETJMP_FLOAT128
So local and global jmp_buf variables are allways well aligned by the C compiler(s)

The jpeg problem was caused by putting the jmp_buf into a structure.
Apparently, gcc and clang fail to correctly handle that case
(they should first align the whole struct on 16 bytes then align the offset of the jmp_buf member).

There are other cases that will be problematic in Win64 exactly like the jpeg case, for example I see:
siglongjmp((vmCallbackContext->trampoline)... in returnAsThroughCallbackContext
longjmp(GIV(jmpBuf)[GIV(jmpDepth)]...in callbackLeave (only #if SQ_USE_GLOBAL_STRUCT)

We should memcpy these to a local jmp_buf for WIN64 compatibility.

But the VM failed before ever reaching one of these callbacks (we should have none in Squeak by default)

So, wrong guess from my side for the moment, seeing longjmp on the call stack raised that false alarm.

 

2017-03-19 21:03 GMT+01:00 Nicolas Cellier <[hidden email]>:
It's necessary to hack the CogX64Compiler SysV class var initialization and generate a win64 specific cogitX64.c.


2017-03-19 20:34 GMT+01:00 Nicolas Cellier <[hidden email]>:
Hi Clement,
it's been a while since I last tested, but in a few words:
- win64 use it's own ABI
- we have to assign the registers differently than sysV
- the experiments I did resulted in VM crashing early (before opening window)

Nicolas

2017-03-19 20:29 GMT+01:00 Clément Bera <[hidden email]>:
 
Thank you very much for doing Nicolas. It is very important for many Pharo users to use Pharo 64 bits on Windows.

What are the problems you have when trying to build the VM with the JIT that you don't have when building the stack VM ? Is it about API to make the memory executable, is it about calling conventions ?

On Sun, Mar 19, 2017 at 12:14 PM, Nicolas Cellier <[hidden email]> wrote:
 

2017-03-19 17:31 GMT+01:00 Nicolas Cellier <[hidden email]>:
Hi,
I've built a 64bits pharo.stack.spur VM for windows on my machine,
and I'm uploading the changes to opensmalltalk-vm in branch
build_pharo_win32_with_cygwin

If the appveyor job correctly succeed, I will emit a pull request.

The VM does not have the SqueakSSL plugin yet.

The 64bits squeak/pharo.cog.spur JIT for windows is still to come,
but I did not work on it for a few months...
One thing at a time.

Let's cross finger

Nicolas











--
_,,,^..^,,,_
best, Eliot



--
_,,,^..^,,,_
best, Eliot



--
_,,,^..^,,,_
best, Eliot





Reply | Threaded
Open this post in threaded view
|

Re: 64bits Pharo VM for windows

Eliot Miranda-2
 
Hi Nicolas,

On Mar 21, 2017, at 5:14 PM, Nicolas Cellier <[hidden email]> wrote:

Now the failure is:

gdb: unknown target exception 0xc0000028 at 0x76f38078

Program received signal ?, Unknown signal.
0x0000000076f38078 in ntdll!RtlRaiseStatus () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll

(gdb) where
#0  0x0000000076f38078 in ntdll!RtlRaiseStatus () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll
#1  0x0000000076ed7eb6 in ntdll!TpAlpcRegisterCompletionList () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll
#2  0x000007fefeb7e5a3 in msvcrt!longjmp () from /cygdrive/c/Windows/system32/msvcrt.dll
#3  0x00000000004314f9 in returnToExecutivepostContextSwitch (inInterpreter=0, switchedContext=1)
    at ../../spur64src/vm/gcc3x-cointerp.c:22130
#4  0x000000000043a110 in activateNewMethod () at ../../spur64src/vm/gcc3x-cointerp.c:15045
#5  0x000000000043c6e2 in interpretMethodFromMachineCode () at ../../spur64src/vm/gcc3x-cointerp.c:19204
#6  0x0000000000442e19 in ceSendsupertonumArgs (selector=204444792, superNormalBar=0, rcvr=206540520, numArgs=0)
    at ../../spur64src/vm/gcc3x-cointerp.c:17228
#7  0x000000000b7000ba in ?? ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)

(gdb) up
#1  0x0000000076ed7eb6 in ntdll!TpAlpcRegisterCompletionList () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll
(gdb) up
#2  0x000007fefeb7e5a3 in msvcrt!longjmp () from /cygdrive/c/Windows/system32/msvcrt.dll
(gdb) up
#3  0x00000000004314f9 in returnToExecutivepostContextSwitch (inInterpreter=0, switchedContext=1)
    at ../../spur64src/vm/gcc3x-cointerp.c:22130
22130                   siglongjmp(reenterInterpreter, ReturnToInterpreter);

(gdb) call printCallStack()
... snip...
          0xf0b138 I Set class(HashedCollection class)>new 0xc4f8ee8: a(n) Set class
          0xf0b168 M FFICallbackThunk class>startUp: 0xdb6b718: a(n) FFICallbackThunk class
          0xf0b1c0 M [] in SmalltalkImage>send:toClassesNamedIn:with: 0xc553d18: a(n) SmalltalkImage
          0xf0b210 I OrderedCollection>do: 0xc8a81d8: a(n) OrderedCollection
          0xf0b260 I SmalltalkImage>send:toClassesNamedIn:with: 0xc553d18: a(n) SmalltalkImage
          0xf0b2b8 I SmalltalkImage>processStartUpList: 0xc553d18: a(n) SmalltalkImage
          0xf0b310 I SmalltalkImage>snapshot:andQuit:withExitCode:embedded: 0xc553d18: a(n) SmalltalkImage
         0xd1187b0 s SmalltalkImage>snapshot:andQuit:embedded:
         0xc79ee20 s SmalltalkImage>snapshot:andQuit:
         0xdc6c6b8 s TheWorldMenu>saveAndQuit
         0xdc6eb20 s TheWorldMenu>doMenuItem:with:
         0xdc6ef98 s [] in MenuItemMorph>invokeWithEvent:
         0xdc6f200 s BlockClosure>ensure:
         0xdc6f2b8 s CursorWithMask(Cursor)>showWhile:
         0xdc6f370 s MenuItemMorph>invokeWithEvent:
...snip...

(gdb) call longPrintOop(aMethodObj)

0x0d781f10:  70/112 d1/209 22/34  e0/224 7c/124 ba/186 31/49  86/134
0x0d781f18:  fe/254
         0xd781ed8: a(n) CompiledMethod (0x468=>0xc4f8168) format 0x1f nbytes 57 hdr8 ..... hash 0x0
 0               0x29 5(0x5) nLits 5 nArgs 0 nTemps 0
 1          0xc32c900 #initialize:
 2          0xc2fa9a8 #basicNew
 3               0x29 5(0x5)
 4          0xc2f9478 #new
 5          0xd759cf0 a(n) Association

This indeed look like HashedCollection class>>new
49 <70> self
50 <D1> send: basicNew
51 <22> pushConstant: 5
52 <E0> send: initialize:
53 <7C> returnTop

So that's the status of win64 cog currently...
I'll stop here for tonight.
Eliot, any clue what to look at?

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.

It may be that longjmp walks the stack (I hope not) looking for the frame containing the setjmp.  As we can see from gdb's stack trace that can't be found.  So finding out whether longjmp is simple or tries to be clever is important.  Hopefully it is simple and just reloads the registers and jumps.


2017-03-22 0:47 GMT+01:00 Nicolas Cellier <[hidden email]>:
Gah, stupid me, I didn't realized that the vm was compiled for SysV...
I need to define -DWIN64ABI somewhere...

2017-03-21 22:18 GMT+01:00 Nicolas Cellier <[hidden email]>:


2017-03-21 7:48 GMT+01:00 Nicolas Cellier <[hidden email]>:
Hi Eliot,
I'll try the assert if I can find a time slot today, otherwise this evening.
I could also have printed the jump_buf address in gdb, but it was too late yesterday ;)


2017-03-21 2:19 GMT+01:00 Eliot Miranda <[hidden email]>:
 


On Mon, Mar 20, 2017 at 6:01 PM, Eliot Miranda <[hidden email]> wrote:
Hi Nicolas,

On Mon, Mar 20, 2017 at 5:56 PM, Eliot Miranda <[hidden email]> wrote:
Hi Nicolas,

On Mon, Mar 20, 2017 at 3:45 PM, Nicolas Cellier <[hidden email]> wrote:
 
Thanks Eliot for pushing WIN64 ABI further!

So the failure is this one:

gdb: unknown target exception 0xc0000028 at 0x774c8078

Program received signal ?, Unknown signal.
0x00000000774c8078 in ntdll!RtlRaiseStatus () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll
(gdb) where
#0  0x00000000774c8078 in ntdll!RtlRaiseStatus () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll
#1  0x0000000077467eb6 in ntdll!TpAlpcRegisterCompletionList () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll
#2  0x000007fefe08e5a3 in msvcrt!longjmp () from /cygdrive/c/Windows/system32/msvcrt.dll
#3  0x0000000000419502 in ceReturnToInterpreter (anOop=176164968) at ../../spur64src/vm/gcc3x-cointerp.c:16504
#4  0x000000000a801086 in ?? ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)

I now suspect the jmp_buf alignment problem that I had to workaround in jpeg plugin:
It must be aligned on 16 bytes boundary in Win64, but sometimes the compiler fails to honour this requirement
See https://github.com/OpenSmalltalk/opensmalltalk-vm/pull/120

Hmph.  So the stack /should/ be aligned on a 16-byte boundary and hence the compiler /should/ be able to maintain the invariant (see platforms/Cross/vm/sqCogStackAlignment.h; in fact on Mac OS X the alignment is 32 bytes).
 
Let me suggest that you add the following to the preamble:

#if WIN64
# define sigsetjmp(jb,ssmf) (assert(((int)jb & 15) == 0, setjmp(jb))
# define siglongjmp(jb,v) (assert(((int)jb & 15) == 0, longjmp(jb,v))
#elif WIN32
...

and make sure there's a self assertCStackWellAligned send in ceReturnToInterpreter.

Hmmm.  I expect we need code in the ceReturnToInterpreterTrampoline that establishes the stack alignment requirement.  ceReturnToInterpreter: would be called from machine code where there is only 8 byte alignment on x64 (& 4 byte alignment on 32-bit VMs).  If you like I can try and implement this tomorrow.

 Looking at the code, that's not necessary.  The trampoline still switches to the C stack, which should be correctly aligned.  So yes, definitely add the "self assertCStackWellAligned" to both ceReturnToInterpreter: and ceBaseFrameReturn:.  It looks like the issue is whether the returnToInterpreter jmpbuf is correctly aligned.



The STACK_ALIGN_BYTES is 16 in good agreement with WIN64 ABI and assertCStackWellAligned() do succeed in ceReturnToInterpreter...

So, I added the assertion on setjmp and longjmp, but they do not fail.
The jmp_buf reenterInterpreter is correctly aligned on 16 bytes boundary.
There is a declaration like this in setjmp.h
 typedef _CRT_ALIGN(16) struct _SETJMP_FLOAT128
So local and global jmp_buf variables are allways well aligned by the C compiler(s)

The jpeg problem was caused by putting the jmp_buf into a structure.
Apparently, gcc and clang fail to correctly handle that case
(they should first align the whole struct on 16 bytes then align the offset of the jmp_buf member).

There are other cases that will be problematic in Win64 exactly like the jpeg case, for example I see:
siglongjmp((vmCallbackContext->trampoline)... in returnAsThroughCallbackContext
longjmp(GIV(jmpBuf)[GIV(jmpDepth)]...in callbackLeave (only #if SQ_USE_GLOBAL_STRUCT)

We should memcpy these to a local jmp_buf for WIN64 compatibility.

But the VM failed before ever reaching one of these callbacks (we should have none in Squeak by default)

So, wrong guess from my side for the moment, seeing longjmp on the call stack raised that false alarm.

 

2017-03-19 21:03 GMT+01:00 Nicolas Cellier <[hidden email]>:
It's necessary to hack the CogX64Compiler SysV class var initialization and generate a win64 specific cogitX64.c.


2017-03-19 20:34 GMT+01:00 Nicolas Cellier <[hidden email]>:
Hi Clement,
it's been a while since I last tested, but in a few words:
- win64 use it's own ABI
- we have to assign the registers differently than sysV
- the experiments I did resulted in VM crashing early (before opening window)

Nicolas

2017-03-19 20:29 GMT+01:00 Clément Bera <[hidden email]>:
 
Thank you very much for doing Nicolas. It is very important for many Pharo users to use Pharo 64 bits on Windows.

What are the problems you have when trying to build the VM with the JIT that you don't have when building the stack VM ? Is it about API to make the memory executable, is it about calling conventions ?

On Sun, Mar 19, 2017 at 12:14 PM, Nicolas Cellier <[hidden email]> wrote:
 

2017-03-19 17:31 GMT+01:00 Nicolas Cellier <[hidden email]>:
Hi,
I've built a 64bits pharo.stack.spur VM for windows on my machine,
and I'm uploading the changes to opensmalltalk-vm in branch
build_pharo_win32_with_cygwin

If the appveyor job correctly succeed, I will emit a pull request.

The VM does not have the SqueakSSL plugin yet.

The 64bits squeak/pharo.cog.spur JIT for windows is still to come,
but I did not work on it for a few months...
One thing at a time.

Let's cross finger

Nicolas











--
_,,,^..^,,,_
best, Eliot



--
_,,,^..^,,,_
best, Eliot



--
_,,,^..^,,,_
best, Eliot





Reply | Threaded
Open this post in threaded view
|

Re: 64bits Pharo VM for windows

Ben Coman
 
On Wed, Mar 22, 2017 at 9:15 AM, Eliot Miranda <[hidden email]> wrote:
>
> It may be that longjmp walks the stack (I hope not) looking for the frame containing the setjmp.  As we can see from gdb's stack trace that can't be found.  So finding out whether longjmp is simple or tries to be clever is important.  Hopefully it is simple and just reloads the registers and jumps.

I've no clue if this is consistent across all implementations, but I
read "Unlike the other approaches we will see, longjmp() does not
iterate over the list of frames, it just blasts through them all at
once with wanton disregard for anything precious or beautiful that
they might have contained."
http://blog.reverberate.org/2013/05/deep-wizardry-stack-unwinding.html

cheers -ben
Reply | Threaded
Open this post in threaded view
|

Re: 64bits Pharo VM for windows

Ben Coman
In reply to this post by Eliot Miranda-2
 
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@.../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

2015-07-21 Corinna Vinschen <[hidden email]>
(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 <[hidden email]>
* 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



And quite off-topic, but much later if compiling against MSVC...
"Programming against the x64 exception handling support, part 3:
Unwind internals (RtlUnwindEx interface)"
http://www.nynaeve.net/?p=105


cheers -ben

On Wed, Mar 22, 2017 at 9:15 AM, Eliot Miranda <[hidden email]> wrote:

>
> Hi Nicolas,
>
> On Mar 21, 2017, at 5:14 PM, Nicolas Cellier <[hidden email]> wrote:
>
> Now the failure is:
>
> gdb: unknown target exception 0xc0000028 at 0x76f38078
>
> Program received signal ?, Unknown signal.
> 0x0000000076f38078 in ntdll!RtlRaiseStatus () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll
>
> (gdb) where
> #0  0x0000000076f38078 in ntdll!RtlRaiseStatus () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll
> #1  0x0000000076ed7eb6 in ntdll!TpAlpcRegisterCompletionList () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll
> #2  0x000007fefeb7e5a3 in msvcrt!longjmp () from /cygdrive/c/Windows/system32/msvcrt.dll
> #3  0x00000000004314f9 in returnToExecutivepostContextSwitch (inInterpreter=0, switchedContext=1)
>     at ../../spur64src/vm/gcc3x-cointerp.c:22130
> #4  0x000000000043a110 in activateNewMethod () at ../../spur64src/vm/gcc3x-cointerp.c:15045
> #5  0x000000000043c6e2 in interpretMethodFromMachineCode () at ../../spur64src/vm/gcc3x-cointerp.c:19204
> #6  0x0000000000442e19 in ceSendsupertonumArgs (selector=204444792, superNormalBar=0, rcvr=206540520, numArgs=0)
>     at ../../spur64src/vm/gcc3x-cointerp.c:17228
> #7  0x000000000b7000ba in ?? ()
> Backtrace stopped: previous frame inner to this frame (corrupt stack?)
>
> (gdb) up
> #1  0x0000000076ed7eb6 in ntdll!TpAlpcRegisterCompletionList () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll
> (gdb) up
> #2  0x000007fefeb7e5a3 in msvcrt!longjmp () from /cygdrive/c/Windows/system32/msvcrt.dll
> (gdb) up
> #3  0x00000000004314f9 in returnToExecutivepostContextSwitch (inInterpreter=0, switchedContext=1)
>     at ../../spur64src/vm/gcc3x-cointerp.c:22130
> 22130                   siglongjmp(reenterInterpreter, ReturnToInterpreter);
>
> (gdb) call printCallStack()
> ... snip...
>           0xf0b138 I Set class(HashedCollection class)>new 0xc4f8ee8: a(n) Set class
>           0xf0b168 M FFICallbackThunk class>startUp: 0xdb6b718: a(n) FFICallbackThunk class
>           0xf0b1c0 M [] in SmalltalkImage>send:toClassesNamedIn:with: 0xc553d18: a(n) SmalltalkImage
>           0xf0b210 I OrderedCollection>do: 0xc8a81d8: a(n) OrderedCollection
>           0xf0b260 I SmalltalkImage>send:toClassesNamedIn:with: 0xc553d18: a(n) SmalltalkImage
>           0xf0b2b8 I SmalltalkImage>processStartUpList: 0xc553d18: a(n) SmalltalkImage
>           0xf0b310 I SmalltalkImage>snapshot:andQuit:withExitCode:embedded: 0xc553d18: a(n) SmalltalkImage
>          0xd1187b0 s SmalltalkImage>snapshot:andQuit:embedded:
>          0xc79ee20 s SmalltalkImage>snapshot:andQuit:
>          0xdc6c6b8 s TheWorldMenu>saveAndQuit
>          0xdc6eb20 s TheWorldMenu>doMenuItem:with:
>          0xdc6ef98 s [] in MenuItemMorph>invokeWithEvent:
>          0xdc6f200 s BlockClosure>ensure:
>          0xdc6f2b8 s CursorWithMask(Cursor)>showWhile:
>          0xdc6f370 s MenuItemMorph>invokeWithEvent:
> ...snip...
>
> (gdb) call longPrintOop(aMethodObj)
>
> 0x0d781f10:  70/112 d1/209 22/34  e0/224 7c/124 ba/186 31/49  86/134
> 0x0d781f18:  fe/254
>          0xd781ed8: a(n) CompiledMethod (0x468=>0xc4f8168) format 0x1f nbytes 57 hdr8 ..... hash 0x0
>  0               0x29 5(0x5) nLits 5 nArgs 0 nTemps 0
>  1          0xc32c900 #initialize:
>  2          0xc2fa9a8 #basicNew
>  3               0x29 5(0x5)
>  4          0xc2f9478 #new
>  5          0xd759cf0 a(n) Association
>
> This indeed look like HashedCollection class>>new
> 49 <70> self
> 50 <D1> send: basicNew
> 51 <22> pushConstant: 5
> 52 <E0> send: initialize:
> 53 <7C> returnTop
>
> So that's the status of win64 cog currently...
> I'll stop here for tonight.
> Eliot, any clue what to look at?
>
>
> 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.
>
> It may be that longjmp walks the stack (I hope not) looking for the frame containing the setjmp.  As we can see from gdb's stack trace that can't be found.  So finding out whether longjmp is simple or tries to be clever is important.  Hopefully it is simple and just reloads the registers and jumps.
>
>
> 2017-03-22 0:47 GMT+01:00 Nicolas Cellier <[hidden email]>:
>>
>> Gah, stupid me, I didn't realized that the vm was compiled for SysV...
>> I need to define -DWIN64ABI somewhere...
>>
>> 2017-03-21 22:18 GMT+01:00 Nicolas Cellier <[hidden email]>:
>>>
>>>
>>>
>>> 2017-03-21 7:48 GMT+01:00 Nicolas Cellier <[hidden email]>:
>>>>
>>>> Hi Eliot,
>>>> I'll try the assert if I can find a time slot today, otherwise this evening.
>>>> I could also have printed the jump_buf address in gdb, but it was too late yesterday ;)
>>>>
>>>>
>>>> 2017-03-21 2:19 GMT+01:00 Eliot Miranda <[hidden email]>:
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> On Mon, Mar 20, 2017 at 6:01 PM, Eliot Miranda <[hidden email]> wrote:
>>>>>>
>>>>>> Hi Nicolas,
>>>>>>
>>>>>> On Mon, Mar 20, 2017 at 5:56 PM, Eliot Miranda <[hidden email]> wrote:
>>>>>>>
>>>>>>> Hi Nicolas,
>>>>>>>
>>>>>>> On Mon, Mar 20, 2017 at 3:45 PM, Nicolas Cellier <[hidden email]> wrote:
>>>>>>>>
>>>>>>>>
>>>>>>>> Thanks Eliot for pushing WIN64 ABI further!
>>>>>>>>
>>>>>>>> So the failure is this one:
>>>>>>>>
>>>>>>>> gdb: unknown target exception 0xc0000028 at 0x774c8078
>>>>>>>>
>>>>>>>> Program received signal ?, Unknown signal.
>>>>>>>> 0x00000000774c8078 in ntdll!RtlRaiseStatus () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll
>>>>>>>> (gdb) where
>>>>>>>> #0  0x00000000774c8078 in ntdll!RtlRaiseStatus () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll
>>>>>>>> #1  0x0000000077467eb6 in ntdll!TpAlpcRegisterCompletionList () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll
>>>>>>>> #2  0x000007fefe08e5a3 in msvcrt!longjmp () from /cygdrive/c/Windows/system32/msvcrt.dll
>>>>>>>> #3  0x0000000000419502 in ceReturnToInterpreter (anOop=176164968) at ../../spur64src/vm/gcc3x-cointerp.c:16504
>>>>>>>> #4  0x000000000a801086 in ?? ()
>>>>>>>> Backtrace stopped: previous frame inner to this frame (corrupt stack?)
>>>>>>>>
>>>>>>>> I now suspect the jmp_buf alignment problem that I had to workaround in jpeg plugin:
>>>>>>>> It must be aligned on 16 bytes boundary in Win64, but sometimes the compiler fails to honour this requirement
>>>>>>>> See https://github.com/OpenSmalltalk/opensmalltalk-vm/pull/120
>>>>>>>
>>>>>>>
>>>>>>> Hmph.  So the stack /should/ be aligned on a 16-byte boundary and hence the compiler /should/ be able to maintain the invariant (see platforms/Cross/vm/sqCogStackAlignment.h; in fact on Mac OS X the alignment is 32 bytes).
>>>>>>>
>>>>>>> Let me suggest that you add the following to the preamble:
>>>>>>>
>>>>>>> #if WIN64
>>>>>>> # define sigsetjmp(jb,ssmf) (assert(((int)jb & 15) == 0, setjmp(jb))
>>>>>>> # define siglongjmp(jb,v) (assert(((int)jb & 15) == 0, longjmp(jb,v))
>>>>>>> #elif WIN32
>>>>>>> ...
>>>>>>>
>>>>>>> and make sure there's a self assertCStackWellAligned send in ceReturnToInterpreter.
>>>>>>
>>>>>>
>>>>>> Hmmm.  I expect we need code in the ceReturnToInterpreterTrampoline that establishes the stack alignment requirement.  ceReturnToInterpreter: would be called from machine code where there is only 8 byte alignment on x64 (& 4 byte alignment on 32-bit VMs).  If you like I can try and implement this tomorrow.
>>>>>
>>>>>
>>>>>  Looking at the code, that's not necessary.  The trampoline still switches to the C stack, which should be correctly aligned.  So yes, definitely add the "self assertCStackWellAligned" to both ceReturnToInterpreter: and ceBaseFrameReturn:.  It looks like the issue is whether the returnToInterpreter jmpbuf is correctly aligned.
>>>>>
>>>
>>>
>>> The STACK_ALIGN_BYTES is 16 in good agreement with WIN64 ABI and assertCStackWellAligned() do succeed in ceReturnToInterpreter...
>>>
>>> So, I added the assertion on setjmp and longjmp, but they do not fail.
>>> The jmp_buf reenterInterpreter is correctly aligned on 16 bytes boundary.
>>> There is a declaration like this in setjmp.h
>>>  typedef _CRT_ALIGN(16) struct _SETJMP_FLOAT128
>>> So local and global jmp_buf variables are allways well aligned by the C compiler(s)
>>>
>>> The jpeg problem was caused by putting the jmp_buf into a structure.
>>> Apparently, gcc and clang fail to correctly handle that case
>>> (they should first align the whole struct on 16 bytes then align the offset of the jmp_buf member).
>>>
>>> There are other cases that will be problematic in Win64 exactly like the jpeg case, for example I see:
>>> siglongjmp((vmCallbackContext->trampoline)... in returnAsThroughCallbackContext
>>> longjmp(GIV(jmpBuf)[GIV(jmpDepth)]...in callbackLeave (only #if SQ_USE_GLOBAL_STRUCT)
>>>
>>> We should memcpy these to a local jmp_buf for WIN64 compatibility.
>>>
>>> But the VM failed before ever reaching one of these callbacks (we should have none in Squeak by default)
>>>
>>> So, wrong guess from my side for the moment, seeing longjmp on the call stack raised that false alarm.
>>>
>>>
>>>>>>
>>>>>>
>>>>>>>> 2017-03-19 21:03 GMT+01:00 Nicolas Cellier <[hidden email]>:
>>>>>>>>>
>>>>>>>>> And currently https://github.com/OpenSmalltalk/opensmalltalk-vm/blob/Cog/spur64src/vm/cogitX64.c is generated for SysV only.
>>>>>>>>> It's necessary to hack the CogX64Compiler SysV class var initialization and generate a win64 specific cogitX64.c.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> 2017-03-19 20:34 GMT+01:00 Nicolas Cellier <[hidden email]>:
>>>>>>>>>>
>>>>>>>>>> Hi Clement,
>>>>>>>>>> it's been a while since I last tested, but in a few words:
>>>>>>>>>> - win64 use it's own ABI
>>>>>>>>>> - we have to assign the registers differently than sysV
>>>>>>>>>> - the experiments I did resulted in VM crashing early (before opening window)
>>>>>>>>>>
>>>>>>>>>> Nicolas
>>>>>>>>>>
>>>>>>>>>> 2017-03-19 20:29 GMT+01:00 Clément Bera <[hidden email]>:
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> Thank you very much for doing Nicolas. It is very important for many Pharo users to use Pharo 64 bits on Windows.
>>>>>>>>>>>
>>>>>>>>>>> What are the problems you have when trying to build the VM with the JIT that you don't have when building the stack VM ? Is it about API to make the memory executable, is it about calling conventions ?
>>>>>>>>>>>
>>>>>>>>>>> On Sun, Mar 19, 2017 at 12:14 PM, Nicolas Cellier <[hidden email]> wrote:
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> And the appveyor builds are green
>>>>>>>>>>>> https://ci.appveyor.com/project/OpenSmalltalk/vm/build/1.0.579
>>>>>>>>>>>>
>>>>>>>>>>>> 2017-03-19 17:31 GMT+01:00 Nicolas Cellier <[hidden email]>:
>>>>>>>>>>>>>
>>>>>>>>>>>>> Hi,
>>>>>>>>>>>>> I've built a 64bits pharo.stack.spur VM for windows on my machine,
>>>>>>>>>>>>> and I'm uploading the changes to opensmalltalk-vm in branch
>>>>>>>>>>>>> build_pharo_win32_with_cygwin
>>>>>>>>>>>>>
>>>>>>>>>>>>> If the appveyor job correctly succeed, I will emit a pull request.
>>>>>>>>>>>>>
>>>>>>>>>>>>> The VM does not have the SqueakSSL plugin yet.
>>>>>>>>>>>>>
>>>>>>>>>>>>> The 64bits squeak/pharo.cog.spur JIT for windows is still to come,
>>>>>>>>>>>>> but I did not work on it for a few months...
>>>>>>>>>>>>> One thing at a time.
>>>>>>>>>>>>>
>>>>>>>>>>>>> Let's cross finger
>>>>>>>>>>>>>
>>>>>>>>>>>>> Nicolas
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> _,,,^..^,,,_
>>>>>>> best, Eliot
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> _,,,^..^,,,_
>>>>>> best, Eliot
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> _,,,^..^,,,_
>>>>> best, Eliot
>>>>>
>>>>
>>>
>>
>
>
Reply | Threaded
Open this post in threaded view
|

Re: 64bits Pharo VM for windows

Ben Coman
 
On Thu, Mar 23, 2017 at 7:06 PM, Ben Coman <[hidden email]> wrote:
btw, here is a comparison of i386 versus x86_64 Cygwin longjmp...
https://www.diffchecker.com/iAMuXTMn


> 2015-07-21 Corinna Vinschen <[hidden email]>
> (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 <[hidden email]>
> * 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

* 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>
Reply | Threaded
Open this post in threaded view
|

Re: 64bits Pharo VM for windows

Eliot Miranda-2
 
Hi Ben,

    see below...

On Thu, May 18, 2017 at 7:59 AM, Ben Coman <[hidden email]> wrote:

On Thu, Mar 23, 2017 at 7:06 PM, Ben Coman <[hidden email]> 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@.../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 <[hidden email]>
> (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 <[hidden email]>
> * 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.


* 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
Reply | Threaded
Open this post in threaded view
|

Re: 64bits Pharo VM for windows

Ben Coman
 
On Fri, May 19, 2017 at 12:10 AM, Eliot Miranda <[hidden email]> wrote:

>
> Hi Ben,
>
>     see below...
>
> On Thu, May 18, 2017 at 7:59 AM, Ben Coman <[hidden email]> wrote:
>>
>>
>> On Thu, Mar 23, 2017 at 7:06 PM, Ben Coman <[hidden email]> 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@.../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 <[hidden email]>
>> > (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 <[hidden email]>
>> > * 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
>