[Vm-dev] latest changes (no idea from when it started) are making FFI win32 crash (and FFI Callbacks are not reliable anymore either)

Ronie Salgado roniesalg at gmail.com
Tue Nov 29 16:30:54 UTC 2016


The last week I was having this exactly same crash in the
MinimalisticHeadless branch, with both MinGW and with Visual Studio. I
managed to get the VM working with MinGW (not yet with MSVC) by using the
following defines,which I copied from the old Pharo CMake scripts:

-DSTACK_ALIGN_BYTES=16 -DALLOCA_LIES_SO_USE_GETSP=0

In the pharo-vm, the CogFamilyWindowsConfig >> #commonCompilerFlags method
starts with the following comment:
commonCompilerFlags
    "omit -ggdb2 to prevent generating debug info"
    "Some flags explanation:

    STACK_ALIGN_BYTES=16 is needed in mingw and FFI (and I suppose on other
modules too).
    DALLOCA_LIES_SO_USE_GETSP=0 Some compilers return the stack address+4
on alloca function,
    then FFI module needs to adjust that. It is NOT the case of mingw.
    For more information see this thread:
http://forum.world.st/There-are-something-fishy-with-FFI-plugin-td4584226.html
    "


2016-11-29 9:32 GMT-03:00 Esteban Lorenzano <estebanlm at gmail.com>:

>
>
> On 29 Nov 2016, at 13:04, Clément Bera <bera.clement at gmail.com> wrote:
>
> Hi,
>
> Can you confirm this bug happen only in Windows ?
>
>
> yes, the crash is just in windows.
> the callback problem is general (note that FFICallbackTests works fine,
> but I think this is related to the fact that it never enters the 2nd
> condition with the qsort function) .
>
>
> Do you have version number (both VMMaker and git commit) of the last
> version you have that was working ?
>
>
> sadly, not… I tried to get the latest working version, but with the mess I
> have to get the VM to build with opensmalltalk-vm, I couldn’t track it.
> I suspect is related to the work on 64bits for windows, but I have no
> proof of that :P
>
> Esteban
>
>
> Thanks.
>
>
> On Tue, Nov 29, 2016 at 11:54 AM, Esteban Lorenzano <estebanlm at gmail.com>
> wrote:
>
>>
>> Hi,
>>
>> So, I’m building the PharoVM along with all his dependencies. For me,
>> this is a major step because I can drop the old build process finally.
>> Now, I’m having serious problems with FFI (that they were not present
>> before), :
>>
>>
>> 1. CRASH IN WINDOWS (32bits):
>>
>> In Win32, it crashes automatically when trying to access this funtion:
>>
>> getEnvSize: nameString
>>         ^ self ffiCall: #( int GetEnvironmentVariableA ( String
>> nameString, nil, 0 ) ) module: #Kernel32
>>
>>  (this works perfectly fine in older versions)
>>
>> 2. CALLBACKS FAILING:
>>
>> Callbacks have problems. The examples passes but they are very simple… as
>> soon as I try to do something complicates (like unqlite bindings or libgit2
>> bindings, who use callbacks intensively), callbacks stops working.
>> I traced the problem up to this method:
>>
>> StackInterpreter>>#returnAs:ThroughCallback:Context:
>>
>> returnAs: returnTypeOop ThroughCallback: vmCallbackContext Context:
>> callbackMethodContext
>>         "callbackMethodContext is an activation of
>> invokeCallback:[stack:registers:jmpbuf:].
>>          Its sender is the VM's state prior to the callback.  Reestablish
>> that state (via longjmp),
>>          and mark callbackMethodContext as dead."
>>         <export: true>
>>         <var: #vmCallbackContext type: #'VMCallbackContext *'>
>>         | calloutMethodContext theFP thePage |
>>         <var: #theFP type: #'char *'>
>>         <var: #thePage type: #'StackPage *'>
>>         ((self isIntegerObject: returnTypeOop)
>>          and: [self isLiveContext: callbackMethodContext]) ifFalse:
>>                 [^false].
>>         calloutMethodContext := self externalInstVar: SenderIndex
>> ofContext: callbackMethodContext.
>>         (self isLiveContext: calloutMethodContext) ifFalse:
>>                 [^false].
>>         "We're about to leave this stack page; must save the current
>> frame's instructionPointer."
>>         self push: instructionPointer.
>>         self externalWriteBackHeadFramePointers.
>>         "Mark callbackMethodContext as dead; the common case is that it
>> is the current frame.
>>          We go the extra mile for the debugger."
>>         (self isSingleContext: callbackMethodContext)
>>                 ifTrue: [self markContextAsDead: callbackMethodContext]
>>                 ifFalse:
>>                         [theFP := self frameOfMarriedContext:
>> callbackMethodContext.
>>                          framePointer = theFP "common case"
>>                                 ifTrue:
>>                                         [(self isBaseFrame: theFP)
>>                                                 ifTrue: [stackPages
>> freeStackPage: stackPage]
>>                                                 ifFalse:
>> "calloutMethodContext is immediately below on the same page.  Make it
>> current."
>>
>> [instructionPointer := (self frameCallerSavedIP: framePointer)
>> asUnsignedInteger.
>>                                                          stackPointer :=
>> framePointer + (self frameStackedReceiverOffset: framePointer) +
>> objectMemory wordSize.
>>                                                          framePointer :=
>> self frameCallerFP: framePointer.
>>                                                          self setMethod:
>> (self frameMethodObject: framePointer).
>>                                                          self
>> restoreCStackStateForCallbackContext: vmCallbackContext.
>>                                                          "N.B. siglongjmp
>> is defines as _longjmp on non-win32 platforms.
>>                                                           This matches
>> the use of _setjmp in ia32abicc.c."
>>                                                          self siglong:
>> vmCallbackContext trampoline jmp: (self integerValueOf: returnTypeOop).
>>                                                          ^true]]
>>                                 ifFalse:
>>                                         [self externalDivorceFrame: theFP
>> andContext: callbackMethodContext.
>>                                          self markContextAsDead:
>> callbackMethodContext]].
>>         "Make the calloutMethodContext the active frame.  The case where
>> calloutMethodContext
>>          is immediately below callbackMethodContext on the same page is
>> handled above."
>>         (self isStillMarriedContext: calloutMethodContext)
>>                 ifTrue:
>>                         [theFP := self frameOfMarriedContext:
>> calloutMethodContext.
>>                          thePage := stackPages stackPageFor: theFP.
>>                          "findSPOf:on: points to the word beneath the
>> instructionPointer, but
>>                           there is no instructionPointer on the top frame
>> of the current page."
>>                          self assert: thePage ~= stackPage.
>>                          stackPointer := (self findSPOf: theFP on:
>> thePage) - objectMemory wordSize.
>>                          framePointer := theFP]
>>                 ifFalse:
>>                         [thePage := self makeBaseFrameFor:
>> calloutMethodContext.
>>                          framePointer := thePage headFP.
>>                          stackPointer := thePage headSP].
>>         instructionPointer := self popStack.
>>         self setMethod: (objectMemory fetchPointer: MethodIndex ofObject:
>> calloutMethodContext).
>>         self setStackPageAndLimit: thePage.
>>         self restoreCStackStateForCallbackContext: vmCallbackContext.
>>          "N.B. siglongjmp is defines as _longjmp on non-win32 platforms.
>>           This matches the use of _setjmp in ia32abicc.c."
>>         self siglong: vmCallbackContext trampoline jmp: (self
>> integerValueOf: returnTypeOop).
>>         "NOTREACHED"
>>         ^true
>>
>> with the first siglongjmp callbacks are passing fine.
>> with the last (it would be if  framePointer = theFP AND !(isBaseFrame:
>> theFP) ) it doesn’t.
>>
>> So… from here I’m a bit lost… I need some help :)
>>
>> thanks,
>> Esteban
>>
>>
>>
>>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20161129/9c4c1534/attachment-0001.html>


More information about the Vm-dev mailing list