Platform requirements
editA process that dumps itself uses the same operating system features as a debugger. Operating systems restrict them, and the restrictions differ between Windows, Linux and macOS.
Supported platforms
| Platform | Requirement |
|---|---|
| Windows | Windows 8.1 or later. The process must be x64, x86 or Arm64; other architectures throw PlatformNotSupportedException |
| Linux | The createdump tool of the .NET runtime, and the permission to attach to the process (see below) |
| macOS | The createdump tool of the .NET runtime, and an executable signed with the get-task-allow entitlement (see below) |
On the other operating systems, Write and WriteAsync throw PlatformNotSupportedException.
createdump ships with the .NET runtime. The package looks for it in the directory of the runtime, then in the directory of the application, where self-contained and single-file applications have it. When it is in neither, the dump throws a FileNotFoundException.
Linux: ptrace
On Linux, createdump attaches to the process with ptrace. When Yama restricts ptrace (kernel.yama.ptrace_scope = 1, the default on Ubuntu), a process can only attach to its descendants, and createdump, a child process, is not allowed to attach to its parent.
- With
ptrace_scope = 1, the package handles it: it callsprctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY)before startingcreatedump, and resets it withprctl(PR_SET_PTRACER, 0)afterward. This overrides any value the application set withPR_SET_PTRACER. - With
ptrace_scope = 2, the process needs theCAP_SYS_PTRACEcapability. - With
ptrace_scope = 3, ptrace is disabled and no dump can be created.
Check the current value with this command:
cat /proc/sys/kernel/yama/ptrace_scopeContainers
In a container, ptrace may be blocked by the seccomp profile of the container runtime, or require the SYS_PTRACE capability. When the dumps fail in a container and work on the host, grant the capability to the container, for instance with --cap-add=SYS_PTRACE for docker run.
macOS: the get-task-allow entitlement
On macOS, createdump can only attach to a process whose executable is signed with the com.apple.security.get-task-allow entitlement.
- The
dotnethost has it:dotnet app.dllcan be dumped. - The app host that the .NET SDK generates (
./app) is signed without entitlements: the dump fails. This is also the case of a test project, whose tests run in the app host of the project.
Re-sign the app host with the entitlement to allow dumps. Create an entitlements file:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.get-task-allow</key>
<true/>
</dict>
</plist>Then sign the executable with it, ad hoc:
codesign --force --sign - --entitlements entitlements.plist ./appThe SDK can write the app host again when it builds the project, so sign it after each build, and after each publish for the published executable. The tests of this package do it with an MSBuild target that runs after the Build target when the project is built on macOS. Apple does not notarize an application that has this entitlement: keep it for the builds you test and diagnose.