It seems I found a fix. I simply copied the code from the "mmap" call over to
"munmap". Can somebody (Igor?) *please* confirm that this is ok to do? My tests
are green but I'm really not sure about this…
Here's the new code for NBMacExternalHeapManager>>unmap:length:
NBMacExternalHeapManager >>unmap: addr length: len
<primitive: #primitiveNativeCall module: #NativeBoostPlugin error:
errorCode>
"unmap memory page"
^ NBFFICallout
cdecl: #( int (uint addr, ulong len) )
emitCall: [:gen | | munmap |
munmap := NativeBoost forCurrentPlatform
getGlobalSymbolPointer: 'munmap'.
gen asm mov: munmap asUImm32 to: gen asm EAX.
gen asm call: gen asm EAX
]
options: #( - optDirectProxyFnAddress )
Cheers,
Max
On 16.11.2012, at 14:11, Max Leske <[email protected]> wrote:
> A followup on the munmap issue:
>
> I think it has something to do with how NativeBoost does the lookup. I looked
> at the way that "mmap" is called and noticed that the selector
> #getGlobalSymbolPointer: is being used. Resolving "munmap" with this selector
> succeeds while doing
>
> NativeBoost loadSymbol: 'munmap' aName fromModule: -2
>
> (which is what happens when the heap manager tries to call "munmap") results
> the stack trace shown below.
>
> I'll keep digging...
>
>
> On 15.11.2012, at 17:20, Max Leske <[email protected]> wrote:
>
>> Hi
>>
>> When NativeBoost tries to call munmap to free a page (happens because a
>> pointer I freed was the last reserved one in that page) it will throw a
>> NBFFICalloutError (every time) because (I think) it can't find the symbol. I
>> have absolutely no clue how to fix this so I'm in need of help.
>>
>> System: OS X 10.8.2
>> Image: 1.4
>> NativeBoost-Core: CamilloBruni.80 (Installed by using the latest NBInstaller)
>>
>> Cheers,
>> Max
>>
>> Here's the stack:
>>
>> 15 November 2012 5:04:23.895 pm
>>
>> VM: Mac OS - intel - 1082 - NBCoInterpreter
>> NativeBoost-CogPlugin-IgorStasenko.14 uuid:
>> da3a649c-e2b2-bd4c-aa2f-9c2ebdb2658a Oct 26 2012,
>> StackToRegisterMappingCogit VMMaker-oscog-EstebanLorenzano.164 uuid:
>> d77dee73-00f5-4d00-847b-00646b08329d Oct 26 2012,
>> git://gitorious.org/cogvm/blessed.git Commit:
>> 48af8595004fd0ec3a3ac6d44c3d7516a87981ca Date: 2012-10-24 16:56:20 +0200 By:
>> Igor Stasenko <[email protected]> Jenkins build #131
>> Image: Pharo1.4 [Latest update: #14457]
>>
>> NBFFICallout class>>signalError:
>> Receiver: NBFFICallout
>> Arguments and temporary variables:
>> errorCode: 1
>> Receiver's instance variables:
>> superclass: NBNativeCodeGen
>> methodDict: a
>> MethodDictionary(#aliasForType:->(NBFFICallout>>#aliasForType: "a...etc...
>> format: 148
>> instanceVariables: #('fnSpec' 'requestor' 'methodArgs'
>> 'coercionMayFail' 'callI...etc...
>> organization: ('type aliases' aliasForType:)
>> ('accessing' anonSpec: callType: c...etc...
>> subclasses: {NBNativeFunctionGen}
>> name: #NBFFICallout
>> classPool: a Dictionary(#CustomErrorCodes->a
>> Dictionary(600->'An instance of NB...etc...
>> sharedPools: nil
>> environment: a SystemDictionary(lots of globals)
>> category: #'NativeBoost-Core-FFI'
>> traitComposition: {}
>> localSelectors: nil
>>
>> NBFFICallout class(NBNativeCodeGen class)>>handleFailureIn:nativeCode:
>> Receiver: NBFFICallout
>> Arguments and temporary variables:
>> aContext:
>> NativeBoostMac32(NativeBoost)>>bootstrapLoadSymbol:ofLength:fromModul...etc...
>> aBlock: [:gen | gen useEmitCall; sender: sender;
>> parseOptions: anOptions; cdecl...etc...
>> method:
>> (NativeBoost>>#bootstrapLoadSymbol:ofLength:fromModule:into: "a
>> Compile...etc...
>> lastError: 1
>> Receiver's instance variables:
>> superclass: NBNativeCodeGen
>> methodDict: a
>> MethodDictionary(#aliasForType:->(NBFFICallout>>#aliasForType: "a...etc...
>> format: 148
>> instanceVariables: #('fnSpec' 'requestor' 'methodArgs'
>> 'coercionMayFail' 'callI...etc...
>> organization: ('type aliases' aliasForType:)
>> ('accessing' anonSpec: callType: c...etc...
>> subclasses: {NBNativeFunctionGen}
>> name: #NBFFICallout
>> classPool: a Dictionary(#CustomErrorCodes->a
>> Dictionary(600->'An instance of NB...etc...
>> sharedPools: nil
>> environment: a SystemDictionary(lots of globals)
>> category: #'NativeBoost-Core-FFI'
>> traitComposition: {}
>> localSelectors: nil
>>
>> NBFFICallout class>>cdecl:emitCall:options:
>> Receiver: NBFFICallout
>> Arguments and temporary variables:
>> functionSpec: #(#NBBootstrapUlong #(#byte #* #symbolName #,
>> #long #symbolLen #,...etc...
>> aCallEmittingBlock: [:gen | gen proxy callFn:
>> #ioLoadSymbol:OfLength:FromModule...etc...
>> anOptions: #(#- #optDirectProxyFnAddress
>> #optAllowExternalAddressPtr)
>> sender:
>> NativeBoostMac32(NativeBoost)>>bootstrapLoadSymbol:ofLength:fromModule:...etc...
>> Receiver's instance variables:
>> superclass: NBNativeCodeGen
>> methodDict: a
>> MethodDictionary(#aliasForType:->(NBFFICallout>>#aliasForType: "a...etc...
>> format: 148
>> instanceVariables: #('fnSpec' 'requestor' 'methodArgs'
>> 'coercionMayFail' 'callI...etc...
>> organization: ('type aliases' aliasForType:)
>> ('accessing' anonSpec: callType: c...etc...
>> subclasses: {NBNativeFunctionGen}
>> name: #NBFFICallout
>> classPool: a Dictionary(#CustomErrorCodes->a
>> Dictionary(600->'An instance of NB...etc...
>> sharedPools: nil
>> environment: a SystemDictionary(lots of globals)
>> category: #'NativeBoost-Core-FFI'
>> traitComposition: {}
>> localSelectors: nil
>>
>> NativeBoostMac32(NativeBoost)>>bootstrapLoadSymbol:ofLength:fromModule:into:
>> Receiver: a NativeBoostMac32
>> Arguments and temporary variables:
>> symbolName: 'munmap'
>> symbolLen: 6
>> moduleHandle: -2
>> returnValueBuffer: #[0 0 0 0 0 0 0 0]
>> Receiver's instance variables:
>> bootstrapping: false
>> insideCallback: nil
>> callbackCounterAddr: @ 16r5F74000
>> extraRootsRegistry: a NBExtraRootsRegistry
>> rootsCell: @ 16r5F7402A
>> gateFunction: @ 16r5F74004
>> heap: a NBMacExternalHeapManager
>>
>> NativeBoostMac32(NativeBoost)>>loadSymbol:fromModule:
>> Receiver: a NativeBoostMac32
>> Arguments and temporary variables:
>> aSymbolName: 'munmap'
>> moduleName: -2
>> bytes: #[0 0 0 0 0 0 0 0]
>> module: -2
>> handle: nil
>> Receiver's instance variables:
>> bootstrapping: false
>> insideCallback: nil
>> callbackCounterAddr: @ 16r5F74000
>> extraRootsRegistry: a NBExtraRootsRegistry
>> rootsCell: @ 16r5F7402A
>> gateFunction: @ 16r5F74004
>> heap: a NBMacExternalHeapManager
>>
>> NativeBoostMac32(NativeBoostLinux32)>>loadSymbol:fromModule:
>> Receiver: a NativeBoostMac32
>> Arguments and temporary variables:
>> aSymbolName: 'munmap'
>> moduleName: -2
>> Receiver's instance variables:
>> bootstrapping: false
>> insideCallback: nil
>> callbackCounterAddr: @ 16r5F74000
>> extraRootsRegistry: a NBExtraRootsRegistry
>> rootsCell: @ 16r5F7402A
>> gateFunction: @ 16r5F74004
>> heap: a NBMacExternalHeapManager
>>
>> NativeBoost class>>loadSymbol:fromModule:
>> Receiver: NativeBoost
>> Arguments and temporary variables:
>> aSymbolName: 'munmap'
>> moduleName: -2
>> Receiver's instance variables:
>> superclass: Object
>> methodDict: a
>> MethodDictionary(#CLibrary->(NativeBoost>>#CLibrary "a CompiledMe...etc...
>> format: 142
>> instanceVariables: #('bootstrapping' 'insideCallback'
>> 'callbackCounterAddr' 'ex...etc...
>> organization: ('retrieving symbols' CLibrary VMModule
>> ioLoadFunction:from: ioLo...etc...
>> subclasses: {NativeBoostLinux32. NativeBoostWin32}
>> name: #NativeBoost
>> classPool: a Dictionary(#Current->a NativeBoostMac32
>> #NBAnnouncer->an Announcer...etc...
>> sharedPools: an OrderedCollection(AJx86Registers
>> NativeBoostConstants)
>> environment: a SystemDictionary(lots of globals)
>> category: #'NativeBoost-Core'
>> traitComposition: {}
>> localSelectors: nil
>>
>> NBMacExternalHeapManager class(Object)>>nbGetSymbolAddress:module:
>> Receiver: NBMacExternalHeapManager
>> Arguments and temporary variables:
>> aName: 'munmap'
>> aModuleNameOrHandle: -2
>> addr: nil
>> Receiver's instance variables:
>> superclass: NBExternalHeapManager
>> methodDict: a
>> MethodDictionary(#mapFlags->(NBMacExternalHeapManager>>#mapFlags ...etc...
>> format: 138
>> instanceVariables: nil
>> organization: ('as yet unclassified' mapFlags
>> mmapLength:prot:flags:into: primA...etc...
>> subclasses: nil
>> name: #NBMacExternalHeapManager
>> classPool: nil
>> sharedPools: an OrderedCollection(NBMacConstants)
>> environment: a SystemDictionary(lots of globals)
>> category: #'NativeBoost-Mac'
>> traitComposition: {}
>> localSelectors: nil
>>
>> [:gen |
>> fnAddress := requestor nbGetSymbolAddress: fnSpec functionName module:
>> aModuleNameOrHandle.
>> fnAddress
>> ifNil: [self error: 'function unavailable'].
>> self optMayGC
>> ifTrue: [asm push: fnAddress asUImm32;
>> mov: NativeBoost callgateFunctionAddress
>> asUImm32 to: EAX;
>> call: EAX]
>> ifFalse: [asm mov: fnAddress asUImm32 to: EAX;
>> call: EAX]] in
>> NBFFICallout>>generateCall:module:
>> Receiver: a NBFFICallout
>> Arguments and temporary variables:
>> aModuleNameOrHandle: a NBFFICallout
>> fnAddress: -2
>> gen: #(nil)
>> Receiver's instance variables:
>> asm: an AJx86Assembler
>> proxy: a NBInterpreterProxy
>> options: a Set(#optCdecl #optAllowByteArraysPtr
>> #optUseStackPointer #optReturnP...etc...
>> method: (NBMacExternalHeapManager>>#unmap:length: "a
>> CompiledMethod(355205120)"...etc...
>> fnSpec: a NBFnSpec
>> requestor: NBMacExternalHeapManager
>> methodArgs: an OrderedCollection('addr' 'len')
>> coercionMayFail: true
>> callInfo: an AJCdeclCallInfo
>>
>> BlockClosure>>valueWithPossibleArgs:
>> Receiver: [:gen |
>> fnAddress := requestor nbGetSymbolAddress: fnSpec functionName module:
>> aModuleNam...etc...
>> Arguments and temporary variables:
>> anArray: an Array(a NBFFICallout a NBInterpreterProxy an
>> AJx86Assembler)
>> Receiver's instance variables:
>> outerContext: NBFFICallout>>generateCall:module:
>> startpc: 91
>> numArgs: 1
>>
>> [aFunctionBodyBlock valueWithPossibleArgs: {self. proxy. asm}.
>> (self optEmitCall
>> or: [self optNoCleanup])
>> ifTrue: [call disableCleanup]] in [:call |
>> self optNoAlignment
>> ifTrue: [call alignment: 1].
>> self pushArguments.
>> coercionMayFail
>> ifTrue: [proxy ifFailedJumpTo: self failedLabel].
>> asm
>> decorateWith: 'FFI: performing a call'
>> during: [aFunctionBodyBlock valueWithPossibleArgs: {self.
>> proxy. asm}.
>> (self optEmitCall
>> or: [self optNoCleanup])
>> ifTrue: [call disableCleanup]]] in
>> NBFFICallout>>generateInstructions:
>> Receiver: a NBFFICallout
>> Arguments and temporary variables:
>> aFunctionBodyBlock: an AJCdeclCallInfo
>> call: [:gen |
>> fnAddress := requestor nbGetSymbolAddress: fnSpec functionName m...etc...
>> Receiver's instance variables:
>> asm: an AJx86Assembler
>> proxy: a NBInterpreterProxy
>> options: a Set(#optCdecl #optAllowByteArraysPtr
>> #optUseStackPointer #optReturnP...etc...
>> method: (NBMacExternalHeapManager>>#unmap:length: "a
>> CompiledMethod(355205120)"...etc...
>> fnSpec: a NBFnSpec
>> requestor: NBMacExternalHeapManager
>> methodArgs: an OrderedCollection('addr' 'len')
>> coercionMayFail: true
>> callInfo: an AJCdeclCallInfo
>>
>> BlockClosure>>ensure:
>> Receiver: [aFunctionBodyBlock valueWithPossibleArgs: {self. proxy. asm}.
>> (self optEmitCall
>> or: [...etc...
>> Arguments and temporary variables:
>> aBlock: [level := level - 1.
>> self
>> addInstruction: (AJInstructionDecoration n...etc...
>> complete: nil
>> returnValue: nil
>> Receiver's instance variables:
>> outerContext: [:call |
>> self optNoAlignment
>> ifTrue: [call alignment: 1].
>> sel...etc...
>> startpc: 155
>> numArgs: 0
>>
>> AJx86Assembler>>decorateWith:during:
>> Receiver: an AJx86Assembler
>> Arguments and temporary variables:
>> annotation: 'FFI: performing a call'
>> aBlock: [aFunctionBodyBlock valueWithPossibleArgs:
>> {self. proxy. asm}.
>> (self o...etc...
>> Receiver's instance variables:
>> instructions: <<error during printing>>
>>
>> [:call |
>> self optNoAlignment
>> ifTrue: [call alignment: 1].
>> self pushArguments.
>> coercionMayFail
>> ifTrue: [proxy ifFailedJumpTo: self failedLabel].
>> asm
>> decorateWith: 'FFI: performing a call'
>> during: [aFunctionBodyBlock valueWithPossibleArgs: {self.
>> proxy. asm}.
>> (self optEmitCall
>> or: [self optNoCleanup])
>> ifTrue: [call disableCleanup]]] in
>> NBFFICallout>>generateInstructions:
>> Receiver: a NBFFICallout
>> Arguments and temporary variables:
>> aFunctionBodyBlock: an AJCdeclCallInfo
>> call: [:gen |
>> fnAddress := requestor nbGetSymbolAddress: fnSpec functionName m...etc...
>> Receiver's instance variables:
>> asm: an AJx86Assembler
>> proxy: a NBInterpreterProxy
>> options: a Set(#optCdecl #optAllowByteArraysPtr
>> #optUseStackPointer #optReturnP...etc...
>> method: (NBMacExternalHeapManager>>#unmap:length: "a
>> CompiledMethod(355205120)"...etc...
>> fnSpec: a NBFnSpec
>> requestor: NBMacExternalHeapManager
>> methodArgs: an OrderedCollection('addr' 'len')
>> coercionMayFail: true
>> callInfo: an AJCdeclCallInfo
>>
>> AJx86Assembler>>performingCall:in:
>> Receiver: an AJx86Assembler
>> Arguments and temporary variables:
>> ci: an AJCdeclCallInfo
>> aBlock: [:call |
>> self optNoAlignment
>> ifTrue: [call alignment: 1].
>> self push...etc...
>> Receiver's instance variables:
>> instructions: <<error during printing>>
>>
>> NBFFICallout>>foreignCall:
>> Receiver: a NBFFICallout
>> Arguments and temporary variables:
>> aBlock: [:call |
>> self optNoAlignment
>> ifTrue: [call alignment: 1].
>> self push...etc...
>> Receiver's instance variables:
>> asm: an AJx86Assembler
>> proxy: a NBInterpreterProxy
>> options: a Set(#optCdecl #optAllowByteArraysPtr
>> #optUseStackPointer #optReturnP...etc...
>> method: (NBMacExternalHeapManager>>#unmap:length: "a
>> CompiledMethod(355205120)"...etc...
>> fnSpec: a NBFnSpec
>> requestor: NBMacExternalHeapManager
>> methodArgs: an OrderedCollection('addr' 'len')
>> coercionMayFail: true
>> callInfo: an AJCdeclCallInfo
>>
>> NBFFICallout>>generateInstructions:
>> Receiver: a NBFFICallout
>> Arguments and temporary variables:
>> aFunctionBodyBlock: [:gen |
>> fnAddress := requestor nbGetSymbolAddress: fnSpec ...etc...
>> instructions: nil
>> Receiver's instance variables:
>> asm: an AJx86Assembler
>> proxy: a NBInterpreterProxy
>> options: a Set(#optCdecl #optAllowByteArraysPtr
>> #optUseStackPointer #optReturnP...etc...
>> method: (NBMacExternalHeapManager>>#unmap:length: "a
>> CompiledMethod(355205120)"...etc...
>> fnSpec: a NBFnSpec
>> requestor: NBMacExternalHeapManager
>> methodArgs: an OrderedCollection('addr' 'len')
>> coercionMayFail: true
>> callInfo: an AJCdeclCallInfo
>>
>> NBFFICallout>>generate:
>> Receiver: a NBFFICallout
>> Arguments and temporary variables:
>> aFunctionBodyBlock: [:gen |
>> fnAddress := requestor nbGetSymbolAddress: fnSpec ...etc...
>> generatedCode: nil
>> Receiver's instance variables:
>> asm: an AJx86Assembler
>> proxy: a NBInterpreterProxy
>> options: a Set(#optCdecl #optAllowByteArraysPtr
>> #optUseStackPointer #optReturnP...etc...
>> method: (NBMacExternalHeapManager>>#unmap:length: "a
>> CompiledMethod(355205120)"...etc...
>> fnSpec: a NBFnSpec
>> requestor: NBMacExternalHeapManager
>> methodArgs: an OrderedCollection('addr' 'len')
>> coercionMayFail: true
>> callInfo: an AJCdeclCallInfo
>>
>> NBFFICallout>>generateCall:module:
>> Receiver: a NBFFICallout
>> Arguments and temporary variables:
>> functionSpec: #(#int #munmap #(#uint #addr #, #ulong #len))
>> aModuleNameOrHandle: -2
>> fnAddress: #(nil)
>> Receiver's instance variables:
>> asm: an AJx86Assembler
>> proxy: a NBInterpreterProxy
>> options: a Set(#optCdecl #optAllowByteArraysPtr
>> #optUseStackPointer #optReturnP...etc...
>> method: (NBMacExternalHeapManager>>#unmap:length: "a
>> CompiledMethod(355205120)"...etc...
>> fnSpec: a NBFnSpec
>> requestor: NBMacExternalHeapManager
>> methodArgs: an OrderedCollection('addr' 'len')
>> coercionMayFail: true
>> callInfo: an AJCdeclCallInfo
>>
>> [:gen | gen sender: sender;
>> cdecl;
>> generateCall: functionSpec module: aModuleName] in
>> NBFFICallout class>>cdecl:module:
>> Receiver: NBFFICallout
>> Arguments and temporary variables:
>> functionSpec: a NBFFICallout
>> aModuleName: #(#int #munmap #(#uint #addr #, #ulong #len))
>> sender: -2
>> gen: NBMacExternalHeapManager>>unmap:length:
>> Receiver's instance variables:
>> superclass: NBNativeCodeGen
>> methodDict: a
>> MethodDictionary(#aliasForType:->(NBFFICallout>>#aliasForType: "a...etc...
>> format: 148
>> instanceVariables: #('fnSpec' 'requestor' 'methodArgs'
>> 'coercionMayFail' 'callI...etc...
>> organization: ('type aliases' aliasForType:)
>> ('accessing' anonSpec: callType: c...etc...
>> subclasses: {NBNativeFunctionGen}
>> name: #NBFFICallout
>> classPool: a Dictionary(#CustomErrorCodes->a
>> Dictionary(600->'An instance of NB...etc...
>> sharedPools: nil
>> environment: a SystemDictionary(lots of globals)
>> category: #'NativeBoost-Core-FFI'
>> traitComposition: {}
>> localSelectors: nil
>>
>> [bytes := aBlock
>> value: (self newForMethod: method)] in
>> NBFFICallout class(NBNativeCodeGen class)>>generateCode:andRetry:
>> Receiver: NBFFICallout
>> Arguments and temporary variables:
>> aBlock: [:gen | gen sender: sender;
>> cdecl;
>> generateCall: functionSpec mod...etc...
>> method: (NBMacExternalHeapManager>>#unmap:length: "a
>> CompiledMethod(355205120)"...etc...
>> bytes: #(nil)
>> Receiver's instance variables:
>> superclass: NBNativeCodeGen
>> methodDict: a
>> MethodDictionary(#aliasForType:->(NBFFICallout>>#aliasForType: "a...etc...
>> format: 148
>> instanceVariables: #('fnSpec' 'requestor' 'methodArgs'
>> 'coercionMayFail' 'callI...etc...
>> organization: ('type aliases' aliasForType:)
>> ('accessing' anonSpec: callType: c...etc...
>> subclasses: {NBNativeFunctionGen}
>> name: #NBFFICallout
>> classPool: a Dictionary(#CustomErrorCodes->a
>> Dictionary(600->'An instance of NB...etc...
>> sharedPools: nil
>> environment: a SystemDictionary(lots of globals)
>> category: #'NativeBoost-Core-FFI'
>> traitComposition: {}
>> localSelectors: nil
>>
>> BlockClosure>>on:do:
>> Receiver: [bytes := aBlock
>> value: (self newForMethod: method)]
>> Arguments and temporary variables:
>> exception: NBRecursionDetect
>> handlerAction: [:ex | ex check: aMethod]
>> handlerActive: true
>> Receiver's instance variables:
>> outerContext: NBFFICallout class(NBNativeCodeGen
>> class)>>generateCode:andRetry:...etc...
>> startpc: 96
>> numArgs: 0
>>
>> NBRecursionDetect class>>in:during:
>> Receiver: NBRecursionDetect
>> Arguments and temporary variables:
>> aMethod: (NBMacExternalHeapManager>>#unmap:length: "a
>> CompiledMethod(355205120)...etc...
>> aBlock: [bytes := aBlock
>> value: (self newForMethod: method)]
>> Receiver's instance variables:
>> superclass: Notification
>> methodDict: a
>> MethodDictionary(#check:->(NBRecursionDetect>>#check: "a Compiled...etc...
>> format: 144
>> instanceVariables: #('method')
>> organization: ('as yet unclassified' check: defaultAction
>> method signalForMetho...etc...
>> subclasses: nil
>> name: #NBRecursionDetect
>> classPool: nil
>> sharedPools: nil
>> environment: a SystemDictionary(lots of globals)
>> category: #'NativeBoost-Core-Errors'
>> traitComposition: {}
>> localSelectors: nil
>>
>> NBFFICallout class(NBNativeCodeGen class)>>generateCode:andRetry:
>> Receiver: NBFFICallout
>> Arguments and temporary variables:
>> aBlock: [:gen | gen sender: sender;
>> cdecl;
>> generateCall: functionSpec mod...etc...
>> retryCtx: NBMacExternalHeapManager>>unmap:length:
>> method: (NBMacExternalHeapManager>>#unmap:length: "a
>> CompiledMethod(355205120)"...etc...
>> newMethod: nil
>> args: nil
>> bytes: #(nil)
>> Receiver's instance variables:
>> superclass: NBNativeCodeGen
>> methodDict: a
>> MethodDictionary(#aliasForType:->(NBFFICallout>>#aliasForType: "a...etc...
>> format: 148
>> instanceVariables: #('fnSpec' 'requestor' 'methodArgs'
>> 'coercionMayFail' 'callI...etc...
>> organization: ('type aliases' aliasForType:)
>> ('accessing' anonSpec: callType: c...etc...
>> subclasses: {NBNativeFunctionGen}
>> name: #NBFFICallout
>> classPool: a Dictionary(#CustomErrorCodes->a
>> Dictionary(600->'An instance of NB...etc...
>> sharedPools: nil
>> environment: a SystemDictionary(lots of globals)
>> category: #'NativeBoost-Core-FFI'
>> traitComposition: {}
>> localSelectors: nil
>>
>> NBFFICallout class(NBNativeCodeGen class)>>handleFailureIn:nativeCode:
>> Receiver: NBFFICallout
>> Arguments and temporary variables:
>> aContext: NBMacExternalHeapManager>>unmap:length:
>> aBlock: [:gen | gen sender: sender;
>> cdecl;
>> generateCall: functionSpec mod...etc...
>> method: (NBMacExternalHeapManager>>#unmap:length: "a
>> CompiledMethod(355205120)"...etc...
>> lastError: 502
>> Receiver's instance variables:
>> superclass: NBNativeCodeGen
>> methodDict: a
>> MethodDictionary(#aliasForType:->(NBFFICallout>>#aliasForType: "a...etc...
>> format: 148
>> instanceVariables: #('fnSpec' 'requestor' 'methodArgs'
>> 'coercionMayFail' 'callI...etc...
>> organization: ('type aliases' aliasForType:)
>> ('accessing' anonSpec: callType: c...etc...
>> subclasses: {NBNativeFunctionGen}
>> name: #NBFFICallout
>> classPool: a Dictionary(#CustomErrorCodes->a
>> Dictionary(600->'An instance of NB...etc...
>> sharedPools: nil
>> environment: a SystemDictionary(lots of globals)
>> category: #'NativeBoost-Core-FFI'
>> traitComposition: {}
>> localSelectors: nil
>>
>> NBFFICallout class>>cdecl:module:
>> Receiver: NBFFICallout
>> Arguments and temporary variables:
>> functionSpec: #(#int #munmap #(#uint #addr #, #ulong #len))
>> aModuleName: -2
>> sender: NBMacExternalHeapManager>>unmap:length:
>> Receiver's instance variables:
>> superclass: NBNativeCodeGen
>> methodDict: a
>> MethodDictionary(#aliasForType:->(NBFFICallout>>#aliasForType: "a...etc...
>> format: 148
>> instanceVariables: #('fnSpec' 'requestor' 'methodArgs'
>> 'coercionMayFail' 'callI...etc...
>> organization: ('type aliases' aliasForType:)
>> ('accessing' anonSpec: callType: c...etc...
>> subclasses: {NBNativeFunctionGen}
>> name: #NBFFICallout
>> classPool: a Dictionary(#CustomErrorCodes->a
>> Dictionary(600->'An instance of NB...etc...
>> sharedPools: nil
>> environment: a SystemDictionary(lots of globals)
>> category: #'NativeBoost-Core-FFI'
>> traitComposition: {}
>> localSelectors: nil
>>
>> NBMacExternalHeapManager>>unmap:length:
>> Receiver: a NBMacExternalHeapManager
>> Arguments and temporary variables:
>> addr: 7380992
>> len: 32768
>> errorCode: 502
>> Receiver's instance variables:
>> pages: a Dictionary(24981504->a NBMemoryPage 100089856->a
>> NBMemoryPage )
>> freeBlocks: an IdentitySet(a NBMemoryBlock( @ 16r17D302E,
>> 17, free) a NBMemoryB...etc...
>> reservedBlocks: a Dictionary(24981504->a NBMemoryBlock(
>> @ 16r17D3000, 38) 24981...etc...
>> sema: a Semaphore()
>>
>> NBMacExternalHeapManager>>primFreePage:
>> Receiver: a NBMacExternalHeapManager
>> Arguments and temporary variables:
>> aMemoryPage: a NBMemoryPage
>> res: nil
>> Receiver's instance variables:
>> pages: a Dictionary(24981504->a NBMemoryPage 100089856->a
>> NBMemoryPage )
>> freeBlocks: an IdentitySet(a NBMemoryBlock( @ 16r17D302E,
>> 17, free) a NBMemoryB...etc...
>> reservedBlocks: a Dictionary(24981504->a NBMemoryBlock(
>> @ 16r17D3000, 38) 24981...etc...
>> sema: a Semaphore()
>>
>> NBMacExternalHeapManager(NBExternalHeapManager)>>freePage:
>> Receiver: a NBMacExternalHeapManager
>> Arguments and temporary variables:
>> aMemoryPage: a NBMemoryPage
>> Receiver's instance variables:
>> pages: a Dictionary(24981504->a NBMemoryPage 100089856->a
>> NBMemoryPage )
>> freeBlocks: an IdentitySet(a NBMemoryBlock( @ 16r17D302E,
>> 17, free) a NBMemoryB...etc...
>> reservedBlocks: a Dictionary(24981504->a NBMemoryBlock(
>> @ 16r17D3000, 38) 24981...etc...
>> sema: a Semaphore()
>>
>> [:page |
>> page length = aMemoryBlock length
>> ifTrue: [self freePage: page.
>> ^ true].
>> nil] in
>> NBMacExternalHeapManager(NBExternalHeapManager)>>checkForFreePage:
>> Receiver: a NBMacExternalHeapManager
>> Arguments and temporary variables:
>> aMemoryBlock: a NBMemoryPage
>> page: a NBMemoryBlock( @ 16r70A000, 32768, free)
>> Receiver's instance variables:
>> pages: a Dictionary(24981504->a NBMemoryPage 100089856->a
>> NBMemoryPage )
>> freeBlocks: an IdentitySet(a NBMemoryBlock( @ 16r17D302E,
>> 17, free) a NBMemoryB...etc...
>> reservedBlocks: a Dictionary(24981504->a NBMemoryBlock(
>> @ 16r17D3000, 38) 24981...etc...
>> sema: a Semaphore()
>>
>> BlockClosure>>cull:
>> Receiver: [:page |
>> page length = aMemoryBlock length
>> ifTrue: [self freePage: page.
>> ^ true].
>> n...etc...
>> Arguments and temporary variables:
>> anArg: a NBMemoryPage
>> Receiver's instance variables:
>> outerContext:
>> NBMacExternalHeapManager(NBExternalHeapManager)>>checkForFreePage...etc...
>> startpc: 41
>> numArgs: 1
>>
>> Dictionary>>at:ifPresent:
>> Receiver: a Dictionary(24981504->a NBMemoryPage 100089856->a
>> NBMemoryPage )
>> Arguments and temporary variables:
>> key: 7380992
>> aBlock: [:page |
>> page length = aMemoryBlock length
>> ifTrue: [self freePage: p...etc...
>> assoc: 7380992->a NBMemoryPage
>> Receiver's instance variables:
>> tally: 2
>> array: an Array(nil 100089856->a NBMemoryPage nil nil
>> 24981504->a NBMemoryPage)...etc...
>>
>> NBMacExternalHeapManager(NBExternalHeapManager)>>checkForFreePage:
>> Receiver: a NBMacExternalHeapManager
>> Arguments and temporary variables:
>> aMemoryBlock: a NBMemoryBlock( @ 16r70A000, 32768, free)
>> Receiver's instance variables:
>> pages: a Dictionary(24981504->a NBMemoryPage 100089856->a
>> NBMemoryPage )
>> freeBlocks: an IdentitySet(a NBMemoryBlock( @ 16r17D302E,
>> 17, free) a NBMemoryB...etc...
>> reservedBlocks: a Dictionary(24981504->a NBMemoryBlock(
>> @ 16r17D3000, 38) 24981...etc...
>> sema: a Semaphore()
>>
>> NBMemoryBlock>>makeFreeFor:
>> Receiver: a NBMemoryBlock( @ 16r70A030, 32720, free)
>> Arguments and temporary variables:
>> heapManager: a NBMacExternalHeapManager
>> Receiver's instance variables:
>> left: a NBMemoryBlock( @ 16r70A000, 32768, free)
>> right: nil
>> address: 7381040
>> length: 32720
>> free: true
>>
>> [| block |
>> block := reservedBlocks
>> removeKey: address
>> ifAbsent: [self error: 'Unable to find a memory
>> block with given address'].
>> block makeFreeFor: self] in
>> NBMacExternalHeapManager(NBExternalHeapManager)>>free:
>> Receiver: a NBMacExternalHeapManager
>> Arguments and temporary variables:
>> address: 7381040
>> block: a NBMemoryBlock( @ 16r70A030, 32720, free)
>> Receiver's instance variables:
>> pages: a Dictionary(24981504->a NBMemoryPage 100089856->a
>> NBMemoryPage )
>> freeBlocks: an IdentitySet(a NBMemoryBlock( @ 16r17D302E,
>> 17, free) a NBMemoryB...etc...
>> reservedBlocks: a Dictionary(24981504->a NBMemoryBlock(
>> @ 16r17D3000, 38) 24981...etc...
>> sema: a Semaphore()
>>
>> [caught := true.
>> self wait.
>> blockValue := mutuallyExcludedBlock value] in Semaphore>>critical:
>> Receiver: a Semaphore()
>> Arguments and temporary variables:
>> <<error during printing>
>> Receiver's instance variables:
>> firstLink: nil
>> lastLink: nil
>> excessSignals: 0
>>
>> BlockClosure>>ensure:
>> Receiver: [caught := true.
>> self wait.
>> blockValue := mutuallyExcludedBlock value]
>> Arguments and temporary variables:
>> aBlock: [caught
>> ifTrue: [self signal]]
>> complete: nil
>> returnValue: nil
>> Receiver's instance variables:
>> outerContext: Semaphore>>critical:
>> startpc: 42
>> numArgs: 0
>>
>> Semaphore>>critical:
>> Receiver: a Semaphore()
>> Arguments and temporary variables:
>> <<error during printing>
>> Receiver's instance variables:
>> firstLink: nil
>> lastLink: nil
>> excessSignals: 0
>>
>> NBMacExternalHeapManager(NBExternalHeapManager)>>free:
>> Receiver: a NBMacExternalHeapManager
>> Arguments and temporary variables:
>> address: 7381040
>> Receiver's instance variables:
>> pages: a Dictionary(24981504->a NBMemoryPage 100089856->a
>> NBMemoryPage )
>> freeBlocks: an IdentitySet(a NBMemoryBlock( @ 16r17D302E,
>> 17, free) a NBMemoryB...etc...
>> reservedBlocks: a Dictionary(24981504->a NBMemoryBlock(
>> @ 16r17D3000, 38) 24981...etc...
>> sema: a Semaphore()
>>
>>
>> --- The full stack ---
>> NBFFICallout class>>signalError:
>> NBFFICallout class(NBNativeCodeGen class)>>handleFailureIn:nativeCode:
>> NBFFICallout class>>cdecl:emitCall:options:
>> NativeBoostMac32(NativeBoost)>>bootstrapLoadSymbol:ofLength:fromModule:into:
>> NativeBoostMac32(NativeBoost)>>loadSymbol:fromModule:
>> NativeBoostMac32(NativeBoostLinux32)>>loadSymbol:fromModule:
>> NativeBoost class>>loadSymbol:fromModule:
>> NBMacExternalHeapManager class(Object)>>nbGetSymbolAddress:module:
>> [:gen |
>> fnAddress := requestor nbGetSymbolAddress: fnSpec functionName module:
>> aModuleNameOrHandle.
>> fnAddress
>> ifNil: [self error: 'function unavailable'].
>> self optMayGC
>> ifTrue: [asm push: fnAddress asUImm32;
>> mov: NativeBoost callgateFunctionAddress
>> asUImm32 to: EAX;
>> call: EAX]
>> ifFalse: [asm mov: fnAddress asUImm32 to: EAX;
>> call: EAX]] in
>> NBFFICallout>>generateCall:module:
>> BlockClosure>>valueWithPossibleArgs:
>> [aFunctionBodyBlock valueWithPossibleArgs: {self. proxy. asm}.
>> (self optEmitCall
>> or: [self optNoCleanup])
>> ifTrue: [call disableCleanup]] in [:call |
>> self optNoAlignment
>> ifTrue: [call alignment: 1].
>> self pushArguments.
>> coercionMayFail
>> ifTrue: [proxy ifFailedJumpTo: self failedLabel].
>> asm
>> decorateWith: 'FFI: performing a call'
>> during: [aFunctionBodyBlock valueWithPossibleArgs: {self.
>> proxy. asm}.
>> (self optEmitCall
>> or: [self optNoCleanup])
>> ifTrue: [call disableCleanup]]] in
>> NBFFICallout>>generateInstructions:
>> BlockClosure>>ensure:
>> AJx86Assembler>>decorateWith:during:
>> [:call |
>> self optNoAlignment
>> ifTrue: [call alignment: 1].
>> self pushArguments.
>> coercionMayFail
>> ifTrue: [proxy ifFailedJumpTo: self failedLabel].
>> asm
>> decorateWith: 'FFI: performing a call'
>> during: [aFunctionBodyBlock valueWithPossibleArgs: {self.
>> proxy. asm}.
>> (self optEmitCall
>> or: [self optNoCleanup])
>> ifTrue: [call disableCleanup]]] in
>> NBFFICallout>>generateInstructions:
>> AJx86Assembler>>performingCall:in:
>> NBFFICallout>>foreignCall:
>> NBFFICallout>>generateInstructions:
>> NBFFICallout>>generate:
>> NBFFICallout>>generateCall:module:
>> [:gen | gen sender: sender;
>> cdecl;
>> generateCall: functionSpec module: aModuleName] in
>> NBFFICallout class>>cdecl:module:
>> [bytes := aBlock
>> value: (self newForMethod: method)] in
>> NBFFICallout class(NBNativeCodeGen class)>>generateCode:andRetry:
>> BlockClosure>>on:do:
>> NBRecursionDetect class>>in:during:
>> NBFFICallout class(NBNativeCodeGen class)>>generateCode:andRetry:
>> NBFFICallout class(NBNativeCodeGen class)>>handleFailureIn:nativeCode:
>> NBFFICallout class>>cdecl:module:
>> NBMacExternalHeapManager>>unmap:length:
>> NBMacExternalHeapManager>>primFreePage:
>> NBMacExternalHeapManager(NBExternalHeapManager)>>freePage:
>> [:page |
>> page length = aMemoryBlock length
>> ifTrue: [self freePage: page.
>> ^ true].
>> nil] in
>> NBMacExternalHeapManager(NBExternalHeapManager)>>checkForFreePage:
>> BlockClosure>>cull:
>> Dictionary>>at:ifPresent:
>> NBMacExternalHeapManager(NBExternalHeapManager)>>checkForFreePage:
>> NBMemoryBlock>>makeFreeFor:
>> [| block |
>> block := reservedBlocks
>> removeKey: address
>> ifAbsent: [self error: 'Unable to find a memory
>> block with given address'].
>> block makeFreeFor: self] in
>> NBMacExternalHeapManager(NBExternalHeapManager)>>free:
>> [caught := true.
>> self wait.
>> blockValue := mutuallyExcludedBlock value] in Semaphore>>critical:
>> BlockClosure>>ensure:
>> Semaphore>>critical:
>> NBMacExternalHeapManager(NBExternalHeapManager)>>free:
>> - - - - - - - - - - - - - - -
>> - - - - - - - - - - - - - - - - - -
>> NativeBoostMac32(NativeBoostLinux32)>>free:
>> NativeBoost class>>free:
>> NBExternalAddress>>free
>> [:pointer | pointer value free] in LimboCommand>>freePointers
>> Set>>do:
>> LimboCommand>>freePointers
>> [self freePointers] in LimboCommand>>run
>> BlockClosure>>ensure:
>> LimboCommand>>run
>> Limbo>>run:arguments:
>> Limbo>>runSh:
>> Limbo class>>runSh:
>> [limbo := Limbo runSh: '/bin/echo ' , arg] in
>> LimboTest>>testShellCommandWithNewLines
>> [aBlock value.
>> false] in LimboTest(TestCase)>>executeShould:inScopeOf:
>> BlockClosure>>on:do:
>> LimboTest(TestCase)>>executeShould:inScopeOf:
>> LimboTest(TestCase)>>shouldnt:raise:
>> LimboTest>>testShellCommandWithNewLines
>> LimboTest(TestCase)>>performTest
>> [self setUp.
>> self performTest] in LimboTest(TestCase)>>runCase
>> BlockClosure>>ensure:
>> LimboTest(TestCase)>>runCase
>> [(self class selector: testSelector) runCase] in LimboTest(TestCase)>>debug
>> BlockClosure>>ensure:
>> LimboTest(TestCase)>>debug
>> OBCmdRunTests>>execute
>> [:each |
>> (each isActive
>> and: [each isEnabled])
>> ifTrue: [each execute.
>> ^ true].
>> nil] in OBNodeCommandScan(OBCommandScan)>>processKeystroke:withNode:for:
>> OrderedCollection>>do:
>> OBNodeCommandScan(OBCommandScan)>>processKeystroke:withNode:for:
>> [:each |
>> (scan
>> processKeystroke: aCharacter asKeystroke
>> withNode: each
>> for: self)
>> ifTrue: [^ self].
>> nil] in OBColumn>>keystroke:from:
>> OrderedCollection>>reverseDo:
>> OBColumn>>keystroke:from:
>> OBPluggableListMorph(PluggableListMorph)>>modifierKeyPressed:
>> OBPluggableListMorph(PluggableListMorph)>>keyStroke:
>> OBPluggableListMorph(Morph)>>handleKeystroke:
>> KeyboardEvent>>sentTo:
>> OBPluggableListMorph(Morph)>>handleEvent:
>> MorphicEventDispatcher>>dispatchDefault:with:
>> MorphicEventDispatcher>>dispatchEvent:with:
>> OBPluggableListMorph(Morph)>>processEvent:using:
>> OBPluggableListMorph(Morph)>>processEvent:
>> OBPluggableListMorph(PluggableListMorph)>>handleFocusEvent:
>> [ActiveHand := self.
>> ActiveEvent := anEvent.
>> result := focusHolder
>> handleFocusEvent: (anEvent
>> transformedBy: (focusHolder
>> transformedFrom: self))] in HandMorph>>sendFocusEvent:to:clear:
>> [aBlock value] in PasteUpMorph>>becomeActiveDuring:
>> BlockClosure>>on:do:
>> PasteUpMorph>>becomeActiveDuring:
>> HandMorph>>sendFocusEvent:to:clear:
>> HandMorph>>sendEvent:focus:clear:
>> HandMorph>>sendKeyboardEvent:
>> HandMorph>>handleEvent:
>> HandMorph>>processEvents
>> [:h |
>> ActiveHand := h.
>> h processEvents.
>> ActiveHand := nil] in WorldState>>doOneCycleNowFor:
>> Array(SequenceableCollection)>>do:
>> WorldState>>handsDo:
>> WorldState>>doOneCycleNowFor:
>> WorldState>>doOneCycleFor:
>> PasteUpMorph>>doOneCycle
>> [[World doOneCycle.
>> Processor yield.
>> false] whileFalse.
>> nil] in MorphicUIManager>>spawnNewProcess
>> [self value.
>> Processor terminateActive] in BlockClosure>>newProcess
>>
>