Example driver project crashes

Hi, I am trying to run an example driver project from https://developer.apple.com/documentation/driverkit/communicating_between_a_driverkit_extension_and_a_client_app?language=objc

The project compiles fine, the driver extension is successfully installed and running, however when the client application tries to communicate with the driver (calls IOConnectCallScalarMethod CppUserClient/main.cpp, line 236), the driver crashes, even though there are no modifications of the example code. Does anybody know how to fix it?

The project doesn't use any provisioning profile, all three targets are signed to run locally as described in the link.

My system:

  • MacOS 11.5.2 BigSur

  • Apple M1 chip

  • XCode 13.2.1

  • System Integrity Protection status: disabled.

  • systemextensionsctl developer: Developer mode is on

  • also ran command "sudo nvram boot-args=-arm64e_preview_abi"

Answered by in 705097022

It looks like there is an issue with Big Sur and Xcode 13.1 and later causing this problem. The problem shouldn't be present if you upgrade to Monterey.

Accepted Answer

It looks like there is an issue with Big Sur and Xcode 13.1 and later causing this problem. The problem shouldn't be present if you upgrade to Monterey.

thanks, after upgrade to Monterey the issue is gone

@Drewbadour - does this mean that it is not possible to use Xcode 13.1 and later to build DEXTs that work on both Big Sur and Monterey?

None of the workarounds (get users to upgrade to Monterey, build the dext on Xcode 12, etc.) seemed particularly attractive or sustainable, so I've finally done a deep dive on this and figured out the problem.

The change that introduces the crash is that starting with DriverKit 21, IOUserClient::ExternalMethod is annotated to run on a named dispatch queue rather than the default dispatch queue: QUEUENAME(IOUserClientQueueExternalMethod). According to the documentation, this queue is by default the dispatch queue, but I guess this association is only made in the DriverKit 21+ runtime, while macOS 11/DriverKit 20 doesn't have an entry for it in its dispatch queue name table by default.

You can work around the issue quite easily by adding the entry yourself, using something like:

IODispatchQueue* default_queue = nullptr;
kern_return_t res = uc->CopyDispatchQueue(kIOServiceDefaultQueueName, &default_queue);
if (res == KERN_SUCCESS && default_queue != nullptr)
{
    res = uc->SetDispatchQueue(kIOUserClientQueueNameExternalMethod, default_queue);
}
OSSafeReleaseNULL(default_queue);

This explicitly sets the kIOUserClientQueueNameExternalMethod queue to the object's default queue. You'll want to do this during init or Start of any user client subclass, and it's of course not needed if you're otherwise explicitly setting the external method queue; make sure to get the order right if you're changing the user client's default queue and want external methods to run on the same queue.

Example driver project crashes
 
 
Q