Illegal Instruction: 4 OS X libdispatch


(Tyler Cloutier) #1

Hi everyone,

I’m creating a Swift package that uses Dispatch on OS X, but I am getting an Illegal Instruction error after I register my block for an event. Specifically, a UD2 instruction inside of libdispatch:

Process 16425 stopped
* thread #1: tid = 0x68d099, 0x00007fff814aa360 libdispatch.dylib`_dispatch_xref_dispose + 23, queue = 'com.apple.main-thread', stop reason = EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
    frame #0: 0x00007fff814aa360 libdispatch.dylib`_dispatch_xref_dispose + 23
libdispatch.dylib`_dispatch_xref_dispose:
-> 0x7fff814aa360 <+23>: ud2

Does this look like a compiler error, or have I somehow configured my package wrong? I haven’t used any funky compiler flags. I do know that if I set my min version to 10.7 or 10.6 I do not get the error. This is the offending function:

public func listen(backlog: Int = 32, onConnect: (clientConnection: TCPServer) -> ()) throws {
        let ret = system_listen(fd.rawValue, Int32(backlog))
        if ret != 0 {
            throw Error(rawValue: errno)
        }
        let dispatchSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, UInt(fd.rawValue), 0, dispatch_get_main_queue())
// dispatch_source_cancel(dispatchSource)
// dispatch_resume(dispatchSource)
        dispatch_source_set_event_handler(dispatchSource) { [fd = self.fd] in
            var socketAddress = sockaddr()
            var sockLen = socklen_t(SOCK_MAXADDRLEN)
            
            let ret = system_accept(fd.rawValue, &socketAddress, &sockLen)
            if ret == StandardFileDescriptor.invalid.rawValue {
                fatalError()
            }
            let clientFileDescriptor = SocketFileDescriptor(rawValue: ret, socketType: SocketType.stream, addressFamily: fd.addressFamily)
            let clientConnection = TCPServer(loop: self.loop, fd: clientFileDescriptor)
            onConnect(clientConnection: clientConnection)
        }
    }

If it is a bug, where should I file it? Any help would be much appreciated!

Thanks,

Tyler


(Quinn “The Eskimo!”) #2

Intel code uses the `ud2` illegal instruction for `__builtin_trap`, that is, as a way for the code to stop when some sort of error has been detected.

In your case I believe that you’re using your dispatch source incorrectly. Specifically:

* You should hold on to a reference to `dispatchSource`.

* You need to `dispatch_resume` the source before it’ll do anything.

Share and Enjoy

···

On 1 May 2016, at 19:33, Tyler Fleming Cloutier via swift-users <swift-users@swift.org> wrote:

I’m creating a Swift package that uses Dispatch on OS X, but I am getting an Illegal Instruction error after I register my block for an event. Specifically, a UD2 instruction inside of libdispatch:

--
Quinn "The Eskimo!" <http://www.apple.com/developer/>
Apple Developer Relations, Developer Technical Support, Core OS/Hardware


(Tyler Cloutier) #3

Thanks for the reply, Quinn!

Yep, you’re spot on. The dispatchSource is immediately dealloc’d at the end of the function. The resume I had in there, but I forgot to move it back and uncomment it.

So here’s another interesting question, if I add

_ = dispatchSource

to my closure, I can have the closure keep a reference. However, I’ve two concerns with that. One is that looks like something that the compiler might try to optimize out, although in this case perhaps it can’t because of the effect on reference counting. And the second is that I don’t know if the dispatchSource holds a reference to the closure. It seems like it’s possible that it doesn’t, in which case I would avoid a retain cycle.

My motivation for doing something like that is that I would prefer not to make the listen function mutating inside my struct.

···

On May 2, 2016, at 1:16 AM, Quinn The Eskimo! via swift-users <swift-users@swift.org> wrote:

On 1 May 2016, at 19:33, Tyler Fleming Cloutier via swift-users <swift-users@swift.org> wrote:

I’m creating a Swift package that uses Dispatch on OS X, but I am getting an Illegal Instruction error after I register my block for an event. Specifically, a UD2 instruction inside of libdispatch:

Intel code uses the `ud2` illegal instruction for `__builtin_trap`, that is, as a way for the code to stop when some sort of error has been detected.

In your case I believe that you’re using your dispatch source incorrectly. Specifically:

* You should hold on to a reference to `dispatchSource`.

* You need to `dispatch_resume` the source before it’ll do anything.

Share and Enjoy
--
Quinn "The Eskimo!" <http://www.apple.com/developer/>
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(Quinn “The Eskimo!”) #4

I recommend that you be explicit about your source references. If this struct owns the source, have it maintain a strong reference to the source. In your case it seems that `fd` is an attribute of the struct, so you could create the source when the struct is initialised with `fd`. You don’t have to configure or resume it at that point, just create it.

Share and Enjoy

···

On 3 May 2016, at 18:02, Tyler Fleming Cloutier <cloutiertyler@aol.com> wrote:

My motivation for doing something like that is that I would prefer not to make the listen function mutating inside my struct.

--
Quinn "The Eskimo!" <http://www.apple.com/developer/>
Apple Developer Relations, Developer Technical Support, Core OS/Hardware


(Tyler Cloutier) #5

My motivation for doing something like that is that I would prefer not to make the listen function mutating inside my struct.

I recommend that you be explicit about your source references. If this struct owns the source, have it maintain a strong reference to the source. In your case it seems that `fd` is an attribute of the struct, so you could create the source when the struct is initialised with `fd`. You don’t have to configure or resume it at that point, just create it.

Share and Enjoy

Yep that would work, however, it’s a little trickier if I want to have a protocol extension:

https://github.com/TheArtOfEngineering/Edge/blob/master/Sources/IOStream.swift

I could just have a readonly var which just references the underlying dispatch_source_t though!

Thanks for the help!

···

On May 3, 2016, at 10:11 AM, Quinn The Eskimo! via swift-users <swift-users@swift.org> wrote:
On 3 May 2016, at 18:02, Tyler Fleming Cloutier <cloutiertyler@aol.com> wrote:

--
Quinn "The Eskimo!" <http://www.apple.com/developer/>
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users