Open brianrob opened 1 year ago
@lateralusX
Tagging subscribers to 'os-maccatalyst': @steveisok, @akoeplinger See info in area-owners.md if you want to be subscribed.
Author: | brianrob |
---|---|
Assignees: | - |
Labels: | `EventPipe`, `untriaged`, `os-maccatalyst`, `area-Diagnostics-mono`, `needs-area-label` |
Milestone: | - |
Running an application inside the sandbox on macOS
either as an OSX
or MacCatalyst
app gets their file system rooted to ~/Libraries/Containers/<apps bundle id>/Data
, and can not create any files outside that folder. CoreCLR OSX
apps and Mono MacCatalyst
apps uses EventPipe
IPC channels for its diagnostic server implementation, and since Unix Domain Sockets (UDS) uses file system, it will fail to create the UDS if it uses a path outside the sandboxed file system.
Diagnostic tools asdotnet-trace
gets installed as a global tool and runs as a regular OSX
app meaning it won't be part of the apps sandbox and will get a different default tmp directory setup compared to the sandboxed app. This means that the default UDS won't be visible to the diagnostic tools if they don't follow a specific naming pattern based out of the default tmp directory. Since sandboxed apps won't have its default tmp dir setup as other apps, the default UDS created by sandboxed apps won't be visible to diagnostic tools like dotnet-trace
.
One solution could be to use the reverse connect model for diagnostic tooling, in that case the sandboxed app could connect to a UDS created by for example dotnet-trace
inside the sandboxed apps file system setup the app using DOTNET_DiagnosticPorts
and let it connect to the UDS, that should work but comes with a hard limitation. OnmacOS
the max length of an UDS path is set by the OS and can only be up to 104 characters long. Since the path needs to be inside the apps sandboxed file system that includes the apps bundle id, it will break as soon as the apps bundle id is long enough, but as long as the full UDS path used in the reverse connect model is shorter than 104 characters this could be used as a workaround, /Users/xxx/Library/Containers/<app bundle id>/Data
, that gives us ~70 characters for user <uid> + <app bundle id> + <name of UDS file>
. If that exceeds ~70 characters then apps will fail to create the UDS.
For the default UDS listener things are a little more complicated, first, it uses a unique naming schema based out of default tmp path, meaning that default UDS listeners created by sandboxed apps won't be visible to diagnostic tooling. Second, the default naming schema of default UDS listeners adds a number of characters to the total path length, by default the default diagnostic server UDS listener has the following format, dotnet-diagnostic-<pid>-<key>-socket
, 26 characters + <pid>
+ <key>
that will be reduced from the 70 characters that is available for <uid>
+ <app bundle id>
+ <name>
of UDS. Here is an example of the default HelloWorld samples UDS path:
/Users/<uid>/Library/Containers/net.dot-HelloiOS/Data/tmp/dotnet-diagnostic-2460-1698654835-socket
so 93 characters + <uid>
is getting very close to the 104 character limit.
If however the default UDS path is short enough and created inside the apps sandboxed file system it should be possible to manually connect diagnostic tooling using the --diagnostic-port <uds path>,connect
argument.
There are a couple of workarounds to overcome this issue:
<uid>
running the app + the length of the <app bundle id>
, if full UDS path falls within 104 characters, then run diagnostic tools like dotnet-trace
using --diagnostic-port <uds path>,connect
to connect to the default UDS listener.dotnet-trace
within apps sandboxed file system and that it gets a full path below 104 characters. Start up app with the DOTNET_DiagnosticPorts
environment variable set to <uds path>
, see https://learn.microsoft.com/en-us/dotnet/core/diagnostics/dotnet-trace#use-diagnostic-port-to-collect-a-trace-from-app-startupNOTE that all of above must fit into full UDS path not exceeding the maximum of 104 characters path.
Possible long term solutions:
Switch to TCP/IP as transport for IPC channels when building a sandboxed app, affects both OSX (CoreCLR)
and MacCatalyst (Mono)
. This is how other sandboxed apps runs today, for exampleiOS/tvOS/Android
and will resolve all issues around OS UDS path length limitations. Will require dotnet-dsrouter
to run in order for tools like dotnet-trace
to connect to the sandboxed app + setting env variables in launched app.
Have default UDS path to be shorter if running inside the sandbox, this would open up for longer <uid>
+ <app bundle id>
. Won't solve diagnostic tools not being able to discover the default UDS listener, but increase the chances that full UDS path falls into max path length limits and open up for the possible to use --diagnostic-port <default uds listener path>,connect
in the sandboxed app use case.
Looks like another issue is hitting similar issue but in that case causing issue with CoreCLR managed debugging on sandboxed OSX apps, https://github.com/dotnet/runtime/issues/79852. Managed debugging is using a different set of default UDS listeners, but most likely running into by same underlying issue when trying to debug a sandboxed app.
/cc @tommcdon
Tagging subscribers to this area: @tommcdon See info in area-owners.md if you want to be subscribed.
Description
Construction of the IPC channel fails for applications on OSX that run inside of the sandbox. This results in failures when using any IPC channel-based diagnostic commands (e.g. dotnet-trace).
Reproduction Steps
dotnet-trace collect -p <pid>
Expected behavior
dotnet-trace
is able to attach to the application and capture a trace.Actual behavior
dotnet-trace
isn't able to connect to the application because the diagnostic IPC channel doesn't exist.Regression?
No response
Known Workarounds
Disable the sandbox by re-compiling the application.
Configuration
No response
Other information
No response