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

Clément Bera bera.clement at gmail.com
Tue Nov 29 12:04:02 UTC 2016


Hi,

Can you confirm this bug happen only in Windows ?

Do you have version number (both VMMaker and git commit) of the last
version you have that was working ?

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/c11771f6/attachment.html>


More information about the Vm-dev mailing list