[Vm-dev] latest changes (no idea from when it started) are making FFI win32 crash (and FFI Callbacks are not reliable anymore either)
Esteban Lorenzano
estebanlm at gmail.com
Tue Nov 29 12:32:03 UTC 2016
> 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 <mailto: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/61bf9d85/attachment-0001.html>
More information about the Vm-dev
mailing list