Hello,
I am developing a macOS Launch Daemon (packaged as a bundle) that acts as an XPC server. For debugging purposes, I am trying to run the daemon's executable directly from the terminal via sudo ./mydaemon.app/Contents/MacOS/myexecutable.
Initially, I added the com.apple.security.application-groups entitlement to the daemon. However, when starting the process, it failed to create the XPC service with the following errors:
Unsatisfied entitlements: com.apple.security.application-groups Soft-restriction provisioning profile validation failure: Error Domain=AppleMobileFileIntegrityError Code=-413 "No matching profile found" UserInfo={NSURL=<private>, unsatisfiedEntitlements=<private>, NSLocalizedDescription=No matching profile found}
listener failed to activate: xpc_error=[1: Operation not permitted]
To resolve the profile validation failure, I registered a new App Group in the Apple Developer Portal, generated a new provisioning profile for the daemon that includes this group, and embedded it into the bundle (Contents/embedded.provisionprofile).
Now, the previous profile error is gone, but I am getting a new identity conflict error, and the XPC listener still fails:
Two equal instances have unequal identities. <anon<myproc_name>(501) pid=2818 AUID=501> and <anon<myproc_name>(501)(262) pid=2818 AUID=262> listener failed to activate: xpc_error=[1: Operation not permitted]
My questions are:
What exactly causes the Two equal instances have unequal identities error? I noticed the Audit UID difference (AUID=501 vs AUID=262). Why does NSXPCListener still fail with Operation not permitted? What is the recommended workflow for debugging a Launch Daemon that requires an App Group provisioning profile for XPC communication?
Thank you in advance!
For debugging purposes, I am trying to run the daemon's executable directly from the terminal
This won’t work. For your launchd daemon to work correctly, it must be started by launchd. I explain why that’s the case in XPC and App-to-App Communication.
My general advice for debugging a launchd daemon is:
- Structure your code so that you can do most of your debugging in unit tests, rather than in your daemon. That’ll make your life much easier.
- To unit test your XPC code, use the technique in TN3113 Testing and debugging XPC code with an anonymous listener.
- To debug integration issues:
- Using LLDB’s
--wait-foroption to attach to the daemon shortly after it starts. There’s a similar option in Xcode, under Debug > Attach to Process by PID or Name. - Or if you absolutely need to debug from the first instruction, add the
WaitForDebuggerproperty to yourlaunchdproperty list. See thelaunchd.plistman page for details.
- Using LLDB’s
To resolve the profile validation failure …
Right. For the record, this approach is documented in Signing a daemon with a restricted entitlement.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"