I did some progress:
I realized that there was a memory issue within the sysex.
After that I had another message telling that there is look up issue due to Sandbox
I disabled sandbox for the main app
Now I have another error:
error 10:19:41.751935+0200 TestES Connection will be invalitaded
default 10:19:41.752088+0200 TestES [0x14bf04fd0] invalidated because the current process cancelled the connection by calling xpc_connection_cancel()
error 10:19:41.755230+0200 TestES Connection has not being established!
debug 10:19:41.860192+0200 TestES Call ping
default 10:19:41.861541+0200 tonygo.TestES.Extension [0x123104100] invalidated because the current process cancelled the connection by calling xpc_connection_cancel()
default 10:19:41.861728+0200 tonygo.TestES.Extension [0x123104100] activating connection: mach=false listener=false peer=true name=com.tonygo.TestES.Extension.peer[39800].0x123104100
default 10:19:41.861886+0200 TestES [0x14bf04280] Re-initialization successful; calling out to event handler with XPC_ERROR_CONNECTION_INTERRUPTED
error 10:19:41.861974+0200 TestES Remote process crashed or exited!
So when I send the actual message, the process crashes.
Post
Replies
Boosts
Views
Activity
Thanks :) @DTS Engineer
So the idea is: no app groups as on the end the extension won't be sandboxed?
But what about the GUI application? It is sandboxed right? I asked because the goal of this research work is to have a boilerplate that would be ready for distribution at least standalone with notarization.
There are changes, you adviced: https://github.com/tony-go/TestES/commit/f5dce4ec3226875d68370fa7cd7819d648ecaba8
debug 11:37:26.013395+0200 TestES Establishing IPC Client
default 11:37:26.013593+0200 TestES [0x118005020] activating connection: mach=false listener=false peer=false name=tonygo.TestES.Extension
default 11:37:26.013801+0200 TestES [0x118005020] failed to do a bootstrap look-up: xpc_error=[3: No such process]
default 11:37:26.013825+0200 TestES [0x118005020] invalidated after a failed init
error 11:37:26.016406+0200 TestES Connection has not being established!
So it seems that it is a look up error.
I catched the last one from the invalidationHandler
In parallel, I'll try:
[quote='789142022, DTS Engineer, /thread/756155?answerId=789142022#789142022']
TN3113 Testing and debugging XPC code with an anonymous listener.
[/quote]
I did not resolved the bug we had (but at least it avoided to do wrong stuff).
Now I try to go back to the first logs I got:
debug 14:25:16.056727+0200 TestES SystemExtensionInstaller - Install extension...
default 14:53:35.302403+0200 TestES [0x600003ce0000] activating connection: mach=true listener=false peer=false name=com.apple.sysextd
...
default 14:53:35.312582+0200 TestES [0x120756c90] activating connection: mach=false listener=false peer=false name=(anonymous)
default 14:53:35.312657+0200 TestES [0x600003ce0000] invalidated because the current process cancelled the connection by calling xpc_connection_cancel()
....
default 14:53:35.312657+0200 TestES [0x600003ce0000] invalidated because the current process cancelled the connection by calling xpc_connection_cancel()
....
debug 14:53:35.439389+0200 TestES SystemExtensionInstaller - didFinishWithResult: 0
SystemExtensionInstaller - * are my logs.
So I'm not even sur that other logs are related to my xpc listenner as these messages happen during extension installation.
But what Im sure is that later, when the extension is installed and that the XPCClient has established the conneciton I saw:
debug 14:53:46.575298+0200 TestES Call start
default 14:53:46.576719+0200 tonygo.TestES.Extension [0x14c604b00] invalidated because the current process cancelled the connection by calling xpc_connection_cancel()
default 14:53:46.577816+0200 TestES [0x121a0a870] Re-initialization successful; calling out to event handler with XPC_ERROR_CONNECTION_INTERRUPTED
default 14:53:46.577229+0200 tonygo.TestES.Extension [0x14c604b00] activating connection: mach=false listener=false peer=true name=tonygo.TestES-group.xpc.peer[18172].0x14c604b00
error 14:53:46.577939+0200 TestES Remote process crashed or exited! (Catched with `interruptionHandler`)
(First and last lines is my logs)
The funny part is that if I filter to my logs only:
debug 15:15:47.541145+0200 TestES SystemExtensionInstaller - Install extension...
debug 15:15:47.562760+0200 TestES SystemExtensionInstaller - request actionForReplacingExtension
debug 15:15:47.657196+0200 TestES SystemExtensionInstaller - didFinishWithResult: 0
debug 15:15:47.667428+0200 tonygo.TestES.Extension Starting ES client
debug 15:15:47.669392+0200 tonygo.TestES.Extension ES client started!
debug 15:15:47.676040+0200 tonygo.TestES.Extension Resuming XPC Listener
debug 15:15:47.676227+0200 tonygo.TestES.Extension Resumed
debug 15:15:50.839447+0200 TestES Establishing IPC Client
debug 15:15:50.840981+0200 TestES Connection established
debug 15:15:53.668402+0200 TestES Call ping
error 15:15:53.670891+0200 TestES Remote process crashed or exited!
All seem to happen in the right order.
Well, my advice is that you not try to debug your XPC stuff until you have the ES basics working.
I had one on that commit: https://github.com/tony-go/TestES/commit/26d13577e96f7d2af4f00c4a26e2d0035212612b
This logged appeared: https://github.com/tony-go/TestES/commit/26d13577e96f7d2af4f00c4a26e2d0035212612b#diff-ce8a6f64bfbfec9d1d2a908e35f81afeae2cae4d09f5a318c61e7d64b68b3a83R27
Then I tried to add XPC above it.
That doesn’t make sense. An ES client is a system extension that doesn’t launch on demand. Rather, the system launches when you successfully activate it (and also on each restart).
Okay so the system launch it and the client should be created at this moment. My initial concern was if I had to send messages from the main App, I would like to be sure that the client is working. But my appraoch was wrong. Thanks :)
So the next things to do is:
Start the ES client direclty
Expose a isExtensionRunning or something like that
Use XPC message for pure business logic.
Sounds good?
I dug a bit more and when I explictly call the start function I exposed, I have (Call start is my app log`)
We clearly see libxpc claiming:
[0x13be058c0] invalidated because the current process cancelled the connection by calling xpc_connection_cancel()
So there is another issue with my XPC connection at some points.
That new error is likely going to return is your es_new_client call returning ES_NEW_CLIENT_RESULT_ERR_NOT_PERMITTED.
Hmm it seems that at this point es_new_client is not even called.
Basically the extension resume the NSXPCListener, and expose a start function for the main app.
Then the main app send a message that should start the ES client.
It looks like the listenner does not even react to the message sent by the main app.
Hey Eskimo :wave:
Really happy to see your answer.
I updated my info.plist: https://github.com/tony-go/TestES/commit/eda07758c37654fe7f428fb53689315ee221c4a6
But I still have the same error :/
I took a deeper look at logs, ans see these error logs:
Impossible to know if they are realted or not. I should investigate on my side.
It seems that is not what I'm looking for. In a nutshell I'd like to find a way for a swift class to conform to a class definition from a C++ header file.
Thanks I'll take a look :)
Hey @eskimo :)
Thanks for this clarification about notarisation :)
Did it crash? Did that generate a crash report?
No at all. When I try to run the application I saw these logs:
Unable to register Error Domain=SMAppServiceErrorDomain Code=1 "Operation not permitted" UserInfo={NSLocalizedFailureReason=Operation not permitted}
Received XPC error: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service named W4MF6H9XZ6.com.tonygo.NetworkMonitorApp.group.agent was invalidated: failed at lookup with error 3 - No such process." UserInfo={NSDebugDescription=The connection to service named W4MF6H9XZ6.com.tonygo.NetworkMonitorApp.group.agent was invalidated: failed at lookup with error 3 - No such process.}
That makes totaly sense as the agent never starts ... I checked with the Console application like I usually did, but I see no messages.
I put all my last changed on this branch: https://github.com/tony-go/NetworkMonitor/tree/sma-app-service
Thanks for all these details @eskimo :)
Specifically, if you sandbox your app then you need to sandbox your launchd agent. That means that you need to sign your agent with entitlements: com.apple.security.app-sandbox to enable the sandbox. com.apple.security.application-groups to facility XPC.
These should be present in the entitlements file right?
Specifically, to use XPC in a sandboxed process the XPC endpoint name must be an immediate child of one of your app group IDs. So, going back to my earlier example:
Seems good on my side.
You also need to give your agent an Info.plist. If you continue to use an executable as your agent (rather than putting it in its own bundle) set this up with the Info.plist File and Create Info.plist Section in Binary build settings.
Do we need a Info.plist event with an executbale? When should I put it? "In Contents/MacOS too ?
Also, add .plist to the SMAppService call worked :) But the agent never started, here is the agent plist
Notarising implies that you’re distributing the app directly, which means not on the Mac App Store.
You mean that the app on store are not natorized?
Hey @eskimo, ssup?
Don’t put code, in this case the NetworkMonitor executable, in Contents/Resources. See Placing Content in a Bundle for info on where it should be.
"privileged helper tool - macOS - Contents/Library/LaunchServices/" seems to be appropriate ?
Do you actually want to sandbox this app? If so, let me know because that involves further work.
yeah that is the whole, package a full-blown macOS application with a LaunchAgent (with notarization)
Hi @eskimo 👋
Sorry for the late reply. I was for the last few days. Thanks for your answer.
It worked :) Now I'd like to get rid of the manual launchctl load haha. Then I start exploring SMAppService.
Here is the code: https://github.com/tony-go/NetworkMonitor/tree/sma-app-service/
When I try to register the agent I had this error:
2024-02-09 19:28:18.503557+0100 NetworkMonitorApp[83508:3975925] [all] Unable to read plist at: /Users/tonygorez/Library/Developer/Xcode/DerivedData/NetworkMonitor-ebjjqrpyyilqingmpoykggtnpdjb/Build/Products/Debug/NetworkMonitorApp.app/Contents/Library/LaunchAgents/com.tonygo.NetworkMonitorAgent
Unable to register Error Domain=SMAppServiceErrorDomain Code=108 "Unable to read plist: com.tonygo.NetworkMonitorAgent" UserInfo={NSLocalizedFailureReason=Unable to read plist: com.tonygo.NetworkMonitorAgent}
So I checked that the file is present in the app bundle (I added a copy script for this):
➜ ~ tree /Users/tonygorez/Library/Developer/Xcode/DerivedData/NetworkMonitor-ebjjqrpyyilqingmpoykggtnpdjb/Build/Products/Debug/NetworkMonitorApp.app/
/Users/tonygorez/Library/Developer/Xcode/DerivedData/NetworkMonitor-ebjjqrpyyilqingmpoykggtnpdjb/Build/Products/Debug/NetworkMonitorApp.app/
└── Contents
├── Info.plist
├── Library
│ └── LaunchAgents
│ └── com.tonygo.NetworkMonitorAgent.plist
├── MacOS
│ └── NetworkMonitorApp
├── PkgInfo
├── Resources
│ └── NetworkMonitor
└── _CodeSignature
└── CodeResources
I also check file permissions:
➜ ~ ls -la /Users/tonygorez/Library/Developer/Xcode/DerivedData/NetworkMonitor-ebjjqrpyyilqingmpoykggtnpdjb/Build/Products/Debug/NetworkMonitorApp.app/Contents/Library/LaunchAgents/com.tonygo.NetworkMonitorAgent.plist
-rw-r--r-- 1 tonygorez staff 513 Feb 9 19:14 /Users/tonygorez/Library/Developer/Xcode/DerivedData/NetworkMonitor-ebjjqrpyyilqingmpoykggtnpdjb/Build/Products/Debug/NetworkMonitorApp.app/Contents/Library/LaunchAgents/com.tonygo.NetworkMonitorAgent.plist
The plist format too:
➜ ~ plutil -lint /Users/tonygorez/Library/Developer/Xcode/DerivedData/NetworkMonitor-ebjjqrpyyilqingmpoykggtnpdjb/Build/Products/Debug/NetworkMonitorApp.app/Contents/Library/LaunchAgents/com.tonygo.NetworkMonitorAgent.plist
/Users/tonygorez/Library/Developer/Xcode/DerivedData/NetworkMonitor-ebjjqrpyyilqingmpoykggtnpdjb/Build/Products/Debug/NetworkMonitorApp.app/Contents/Library/LaunchAgents/com.tonygo.NetworkMonitorAgent.plist: OK
And finaly the com.apple.security.files.user-selected.read-only entitlements: https://github.com/tony-go/NetworkMonitor/blob/sma-app-service/NetworkMonitorApp/NetworkMonitorApp.entitlements#L11-L12
I run out of ideas haha :)
I took my inspiration from this: https://developer.apple.com/documentation/servicemanagement/updating-your-app-package-installer-to-use-the-new-service-management-api
I hope you a new track haha 😅
Have a good evening
Cheers
In contrast, if your app is sandboxed, as is the case with the example you linked to, this must be prefixed by an app group.
This is not really clear to me how it should look like, AFAIU the app group is W4MF6H9XZ6.com.tonygo.NetworkMonitorApp, then if I had to prefix it, it could be: W4MF6H9XZ6.com.tonygo.NetworkMonitorApp.com.tonygo.NetworkMonitorAgent that seems way to strange tho.
Also I'm not sure about where the .xpc suffix should stand. It looks like it means the XPC endpoint for this particular app group... Not sure.
--
I try these combinations:
let MACH_SERVICE_NAME = "W4MF6H9XZ6.com.tonygo.NetworkMonitorApp.xpc
and
<key>MachServices</key>
<dict>
<key>W4MF6H9XZ6.com.tonygo.NetworkMonitorApp.xpc</key>
<true/>
</dict>
let MACH_SERVICE_NAME = "W4MF6H9XZ6.com.tonygo.NetworkMonitorApp
and
<key>MachServices</key>
<dict>
<key>W4MF6H9XZ6.com.tonygo.NetworkMonitorApp</key>
<true/>
</dict>
let MACH_SERVICE_NAME = "W4MF6H9XZ6.com.tonygo.NetworkMonitorApp
and
<key>MachServices</key>
<dict>
<key>W4MF6H9XZ6.com.tonygo.NetworkMonitorApp.xpc</key>
<true/>
</dict>