HIDDeviceClient Thread 1: EXC_BREAKPOINT (code=1, subcode=0x1f9e0e13c)

Hi all, I'm trying to write a little utility app that can detect when my bluetooth mouse is connected and turn natural scrolling off. I started by creating a Swift Package with swift package init --type excecutable and then wrote the following code in main.swift:

import CoreHID

let manager = HIDDeviceManager()
let notifications = await manager.monitorNotifications(
  matchingCriteria: [.init(primaryUsage: .genericDesktop(.mouse))]
)
for try await notification in notifications {
  switch notification {
  case .deviceMatched(let device):
    print("Matched:", device.deviceID)
    let client = HIDDeviceClient(deviceReference: device)
    print(await client?.manufacturer ?? "Unknown")

  case .deviceRemoved(let device):
    print("Removed:", device.description)
    let client = HIDDeviceClient(deviceReference: device)
    print(await client?.manufacturer ?? "Unknown")

  @unknown default:
    print("Unknown: \(notification)")
  }
}

This program successfully detects my bluetooth mouse and correctly prints "Logitech", but when it gets to a second device, it crashes with the error message I put in the title: EXC_BREAKPOINT (code=1, subcode=0x1f9e0e13c).

If I run the program without my bluetooth mouse connected, it just crashes immediately so I can only assume this second device is the trackpad.

I added some log statements in addition to the prints so I could check unified logging in Console but nothing really stood out. No code signing errors, no permission denials, nada.

My environment:

  • MacBook Air 13-inch, M3, 2024
  • MacOS 15.1 (24B83)
  • Xcode Version 16.0 (16A242d)
  • swift-tools-version: 6.0
$ swift --version
swift-driver version: 1.115 Apple Swift version 6.0 (swiftlang-6.0.0.9.10 clang-1600.0.26.2)

Target: arm64-apple-macosx15.0

Has anyone seen this before or have ideas on how to investigate further?

Answered by DTS Engineer in 823546022

Thanks for the crash report.

The thing I love about my job is that folks ask random questions and it forces me to learn new stuff (-: I’ve been meaning to play with CoreHID for a while now, so I’m glad your question came along and gave me an excuse.

So, anyway, regarding your crash report, the program name is Playground but it’s nothing to do with Swift Playground, right? Rather, it looks like you built a simple executable package and just happened to name it Playground. That confused me for a while |-:

With that in mind, I put your code into a new command-line tool project and reproduced the crash. AFAIK the issue here is that HIDDeviceClient.init(deviceReference:) is trying to get information about the device from the I/O Registry and that’s trapping because the device is missing a required property, namely, kIOHIDVendorIDKey (aka VendorID).

Consider this function:

func test(device: HIDDeviceClient.DeviceReference) {
    var mainPort: mach_port_t = IO_OBJECT_NULL
    let kr = IOMainPort(mach_port_t(MACH_PORT_NULL), &mainPort)
    assert(kr == kIOReturnSuccess)
    
    let match = IORegistryEntryIDMatching(device.deviceID)
    let service = IOServiceGetMatchingService(mainPort, match)
    assert(service != IO_OBJECT_NULL)

    let cf1 = IORegistryEntryCreateCFProperty(service, kIOHIDPrimaryUsageKey as CFString, nil, 0)?.takeRetainedValue()
    print(cf1)

    let cf2 = IORegistryEntryCreateCFProperty(service, kIOHIDVendorIDKey as CFString, nil, 0)?.takeRetainedValue()
    print(cf2)
}

I inserted a call to this into your program before the call to HIDDeviceClient.init(deviceReference:). When I run this modified program it prints:

Matched: 4294970397
Optional(2)
nil

and then traps. So, as you can see, the HID device in question has the kIOHIDPrimaryUsageKey property but not the kIOHIDVendorIDKey property.

Clearly this is a bug in HIDDeviceClient. It should either allow this property to be absent or it should cleanly and return nil. I encourage you to file a bug about that. Please post your bug number, just for the record.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Please post a crash report, per the instructions in Posting a Crash Report.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Accepted Answer

Thanks for the crash report.

The thing I love about my job is that folks ask random questions and it forces me to learn new stuff (-: I’ve been meaning to play with CoreHID for a while now, so I’m glad your question came along and gave me an excuse.

So, anyway, regarding your crash report, the program name is Playground but it’s nothing to do with Swift Playground, right? Rather, it looks like you built a simple executable package and just happened to name it Playground. That confused me for a while |-:

With that in mind, I put your code into a new command-line tool project and reproduced the crash. AFAIK the issue here is that HIDDeviceClient.init(deviceReference:) is trying to get information about the device from the I/O Registry and that’s trapping because the device is missing a required property, namely, kIOHIDVendorIDKey (aka VendorID).

Consider this function:

func test(device: HIDDeviceClient.DeviceReference) {
    var mainPort: mach_port_t = IO_OBJECT_NULL
    let kr = IOMainPort(mach_port_t(MACH_PORT_NULL), &mainPort)
    assert(kr == kIOReturnSuccess)
    
    let match = IORegistryEntryIDMatching(device.deviceID)
    let service = IOServiceGetMatchingService(mainPort, match)
    assert(service != IO_OBJECT_NULL)

    let cf1 = IORegistryEntryCreateCFProperty(service, kIOHIDPrimaryUsageKey as CFString, nil, 0)?.takeRetainedValue()
    print(cf1)

    let cf2 = IORegistryEntryCreateCFProperty(service, kIOHIDVendorIDKey as CFString, nil, 0)?.takeRetainedValue()
    print(cf2)
}

I inserted a call to this into your program before the call to HIDDeviceClient.init(deviceReference:). When I run this modified program it prints:

Matched: 4294970397
Optional(2)
nil

and then traps. So, as you can see, the HID device in question has the kIOHIDPrimaryUsageKey property but not the kIOHIDVendorIDKey property.

Clearly this is a bug in HIDDeviceClient. It should either allow this property to be absent or it should cleanly and return nil. I encourage you to file a bug about that. Please post your bug number, just for the record.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Thanks for the detailed investigation and glad I could provide an opportunity for you! I've filed FB16503304 as you suggested. Hopefully this gets fixed 😬

Experiencing the same issue, filed under FB16439646.

HIDDeviceClient Thread 1: EXC_BREAKPOINT (code=1, subcode=0x1f9e0e13c)
 
 
Q