
Dump Collect
- 19 installs
- 466 repo stars
- Updated July 25, 2026
- managedcode/dotnet-skills
Helps with ai & agent building tasks.
About
dump-collect is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted coding.
- dump-collect
- AI & Agent Building
- AI-coding skill
Dump Collect by the numbers
- 19 all-time installs (skills.sh)
- +1 installs in the week ending Aug 2, 2026 (Skillselion tracking)
- Ranked #10,571 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 3, 2026 (Skillselion catalog sync)
npx skills add https://github.com/managedcode/dotnet-skills --skill dump-collectAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 19 |
|---|---|
| repo stars | ★ 466 |
| Last updated | July 25, 2026 |
| Repository | managedcode/dotnet-skills ↗ |
What it does
Helps with ai & agent building tasks.
Files
.NET Crash Dump Collection
This skill configures and collects crash dumps for modern .NET applications (CoreCLR and NativeAOT) on Linux, macOS, and Windows — including containers.
Stop Signals
🚨 Read before starting any workflow.
- Stop after dumps are enabled or collected. Do not open, analyze, or triage dump files.
- If the user already has a dump file, this skill does not cover analysis. Let them know analysis is out of scope.
- Do not install analysis tools (dotnet-dump analyze, windbg). Only install collection tools (dotnet-dump collect). Using
lldbfor on-demand dump capture on macOS is allowed — it ships with Xcode command-line tools and is not being used for analysis. - Do not trace root cause of crashes. Report the dump file location and move on.
- Do not modify application code. Configuration is environment-only (env vars, OS settings, container specs).
Step 1 — Identify the Scenario
Ask or determine:
1. Goal: Enable automatic crash dumps, or capture a dump from a running process right now? 2. Platform: Linux, macOS, or Windows? Running in a container (Docker/Kubernetes)? 3. Runtime: CoreCLR or NativeAOT?
Detecting CoreCLR vs NativeAOT
From a binary file (Linux/macOS):
# CoreCLR — has IL metadata / managed entry point
strings <binary> | grep -q "CorExeMain" && echo "CoreCLR"
# NativeAOT — has Redhawk runtime symbols
strings <binary> | grep -q "Rhp" && echo "NativeAOT"
# On macOS/Linux, also try:
nm <binary> 2>/dev/null | grep -qi "Rhp" && echo "NativeAOT"From a binary file (Windows):
# CoreCLR — has a CLI header (IL entry point)
dumpbin /clrheader <binary.exe> | Select-String "CLI Header" -Quiet
# NativeAOT — no CLI header, has Redhawk symbols
dumpbin /symbols <binary.exe> | Select-String "Rhp" -QuietFrom a running process (Linux):
# Resolve the binary, then use the same file checks
BINARY=$(readlink /proc/<pid>/exe)
strings "$BINARY" | grep -q "CorExeMain" && echo "CoreCLR" || echo "NativeAOT"From a running process (macOS):
# Resolve the binary path from the running process
BINARY=$(ps -o comm= -p <pid>)
strings "$BINARY" | grep -q "CorExeMain" && echo "CoreCLR" || echo "NativeAOT"From a running process (Windows PowerShell):
# CoreCLR — loads coreclr.dll
(Get-Process -Id <pid>).Modules.ModuleName -contains "coreclr.dll"
# .NET Framework — loads clr.dll (this skill does not apply)
(Get-Process -Id <pid>).Modules.ModuleName -contains "clr.dll"If the app is .NET Framework (`clr.dll`), stop. This skill covers modern .NET (CoreCLR and NativeAOT) only.
>
If neither CoreCLR nor NativeAOT is detected, stop. This skill only applies to .NET applications — do not proceed.
Step 2 — Load the Appropriate Reference
Based on the scenario identified in Step 1, read the relevant reference file:
| Scenario | Reference |
|---|---|
| CoreCLR app (any platform) | references/coreclr-dumps.md |
| NativeAOT app (any platform) | references/nativeaot-dumps.md |
| Any app in Docker or Kubernetes | references/container-dumps.md (then also load the runtime-specific reference) |
Step 3 — Execute
Follow the instructions in the loaded reference to configure or collect dumps. Always:
1. Confirm the dump output directory exists and has write permissions before enabling collection. 2. Report the dump file path back to the user after collection succeeds. 3. Verify configuration took effect — for env vars, echo them; for OS settings, read them back. 4. Remind the user to disable automatic dumps if they were enabled temporarily — remove or unset DOTNET_DbgEnableMiniDump and related env vars to avoid accumulating dump files.
{
"version": "0.1.0",
"category": "Metrics",
"compatibility": "Requires a .NET repository, build artifacts, traces, dumps, or a runnable app for diagnostics work."
}
Container Crash Dump Collection
| Need | Tool | Runtime | Requires |
|---|---|---|---|
| Automatic dump on crash (CoreCLR) | DOTNET_DbgEnableMiniDump env vars + createdump | CoreCLR | SYS_PTRACE, volume mount |
| Automatic dump on crash (NativeAOT, preferred) | --ulimit core=-1 + core_pattern | NativeAOT | SYS_PTRACE, volume mount |
| Automatic dump on crash (NativeAOT, alternative) | createdump + DOTNET_DbgEnableMiniDump env vars | NativeAOT | SYS_PTRACE, volume mount |
| On-demand from running container | dotnet-dump collect (CoreCLR), gcore (NativeAOT) | Per-runtime | SYS_PTRACE |
| Copy dump out of container | docker cp / kubectl cp | Both | — |
Collecting crash dumps from .NET applications running in Docker or Kubernetes containers requires additional configuration for capabilities, storage, and environment variables.
Note: The%e,%p,%h,%tformat specifiers inDOTNET_DbgMiniDumpNamerequire .NET 7+. On .NET 6, use a literal path instead.
>
Dump types for DOTNET_DbgMiniDumpType: 1=Mini, 2=Heap, 3=Triage, 4=Full. Use 4 for maximum diagnostic value. NativeAOT and CoreCLR single-file apps only support full dumps (type 4).Docker
Required Capability
The SYS_PTRACE capability is required for dotnet-dump collect, createdump, and gcore to attach to processes:
# docker run
docker run --cap-add=SYS_PTRACE -v /tmp/dumps:/dumps myapp
# docker compose# docker-compose.yml
services:
myapp:
image: myapp
cap_add:
- SYS_PTRACE
volumes:
- ./dumps:/dumps
environment:
# CoreCLR automatic crash dumps
DOTNET_DbgEnableMiniDump: "1"
DOTNET_DbgMiniDumpType: "4"
DOTNET_DbgMiniDumpName: "/dumps/%e_%p_%t.dmp"
DOTNET_EnableCrashReport: "1"CoreCLR in Docker
Add environment variables to enable automatic crash dumps. Either in docker run:
docker run --cap-add=SYS_PTRACE \
-v /tmp/dumps:/dumps \
-e DOTNET_DbgEnableMiniDump=1 \
-e DOTNET_DbgMiniDumpType=4 \
-e DOTNET_DbgMiniDumpName="/dumps/%e_%p_%t.dmp" \
-e DOTNET_EnableCrashReport=1 \
myappOr in the Dockerfile (baked into the image):
FROM mcr.microsoft.com/dotnet/aspnet:10.0
# Configure crash dump collection
ENV DOTNET_DbgEnableMiniDump=1
ENV DOTNET_DbgMiniDumpType=4
ENV DOTNET_DbgMiniDumpName="/dumps/%e_%p_%t.dmp"
ENV DOTNET_EnableCrashReport=1
# Create dump directory
RUN mkdir -p /dumps
COPY --from=build /app .
ENTRYPOINT ["dotnet", "myapp.dll"]NativeAOT in Docker
Since NativeAOT only supports full dumps, OS-level core dump mechanisms are the simplest approach — no extra tooling to copy or configure.
Preferred: OS-level core dumps:
docker run --cap-add=SYS_PTRACE \
--ulimit core=-1 \
-v /tmp/dumps:/dumps \
myappNote: You may also need to set the core pattern inside the container. If the host's core_pattern pipes to systemd-coredump, container core dumps may not be written where expected. Override at runtime:
docker run --cap-add=SYS_PTRACE \
--ulimit core=-1 \
--privileged \
-v /tmp/dumps:/dumps \
myapp sh -c 'echo "/dumps/core.%e.%p" > /proc/sys/kernel/core_pattern && exec ./myapp'⚠️ --privileged is needed to write to /proc/sys/kernel/core_pattern. For production, prefer configuring the core pattern on the host instead.
Alternative: Use createdump with DOTNET_DbgEnableMiniDump (same env vars as CoreCLR). Copy createdump next to the app binary in the image:
FROM mcr.microsoft.com/dotnet/runtime-deps:10.0
# Copy createdump from the runtime (match your .NET version)
COPY --from=mcr.microsoft.com/dotnet/runtime:10.0 /usr/share/dotnet/shared/Microsoft.NETCore.App/ /tmp/runtime/
RUN find /tmp/runtime -name createdump -exec cp {} /app/ \; && rm -rf /tmp/runtime/
# Configure crash dump collection
ENV DOTNET_DbgEnableMiniDump=1
ENV DOTNET_DbgMiniDumpType=4
ENV DOTNET_DbgMiniDumpName="/dumps/%e_%p_%t.dmp"
RUN mkdir -p /dumps
COPY --from=build /app .
ENTRYPOINT ["./myapp"]For .NET 11+, use DOTNET_DbgCreateDumpToolPath instead of co-locating:
ENV DOTNET_DbgCreateDumpToolPath=/opt/tools/createdump
ENV DOTNET_DbgEnableMiniDump=1
ENV DOTNET_DbgMiniDumpType=4
ENV DOTNET_DbgMiniDumpName="/dumps/%e_%p_%t.dmp"Run with:
docker run --cap-add=SYS_PTRACE \
-v /tmp/dumps:/dumps \
myappOn-Demand Collection in Docker
# Find the container and process
docker exec <container> dotnet-dump ps # CoreCLR
docker exec <container> sh -c 'ps aux | grep myapp' # NativeAOT
# Collect dump (CoreCLR)
docker exec <container> dotnet-dump collect -p <pid> --output /dumps/myapp.dmp
# Collect dump (NativeAOT — requires gdb/gcore in the image)
docker exec <container> gcore -o /dumps/myapp <pid>
# Copy dump out of container (alternative to volume mount)
docker cp <container>:/dumps/myapp.dmp ./myapp.dmpKubernetes
Pod Spec for CoreCLR
apiVersion: v1
kind: Pod
metadata:
name: myapp
spec:
containers:
- name: myapp
image: myapp:latest
securityContext:
capabilities:
add: ["SYS_PTRACE"]
env:
- name: DOTNET_DbgEnableMiniDump
value: "1"
- name: DOTNET_DbgMiniDumpType
value: "4"
- name: DOTNET_DbgMiniDumpName
value: "/dumps/%e_%p_%t.dmp"
- name: DOTNET_EnableCrashReport
value: "1"
volumeMounts:
- name: dumps
mountPath: /dumps
volumes:
- name: dumps
emptyDir:
sizeLimit: 5Gi # Adjust based on expected dump sizePod Spec for NativeAOT
Preferred: OS-level core dumps (simplest — no extra tooling needed):
apiVersion: v1
kind: Pod
metadata:
name: myapp-nativeaot
spec:
containers:
- name: myapp
image: myapp:latest
securityContext:
capabilities:
add: ["SYS_PTRACE"]
command: ["/bin/sh", "-c"]
args: ["ulimit -c unlimited && exec ./myapp"]
volumeMounts:
- name: dumps
mountPath: /dumps
volumes:
- name: dumps
emptyDir:
sizeLimit: 10GiAlternative: Use createdump (bundled in the image next to the app, or via DOTNET_DbgCreateDumpToolPath on .NET 11+):
apiVersion: v1
kind: Pod
metadata:
name: myapp-nativeaot
spec:
containers:
- name: myapp
image: myapp:latest
securityContext:
capabilities:
add: ["SYS_PTRACE"]
env:
- name: DOTNET_DbgEnableMiniDump
value: "1"
- name: DOTNET_DbgMiniDumpType
value: "4"
- name: DOTNET_DbgMiniDumpName
value: "/dumps/%e_%p_%t.dmp"
# .NET 11+ only — uncomment if createdump is not next to the binary:
# - name: DOTNET_DbgCreateDumpToolPath
# value: "/opt/tools/createdump"
volumeMounts:
- name: dumps
mountPath: /dumps
volumes:
- name: dumps
emptyDir:
sizeLimit: 5GiUsing a Persistent Volume for Dumps
For production, use a PersistentVolumeClaim instead of emptyDir so dumps survive pod restarts:
volumes:
- name: dumps
persistentVolumeClaim:
claimName: dump-storage
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: dump-storage
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 20GiOn-Demand Collection in Kubernetes
# Find the pod and process
kubectl exec <pod> -- dotnet-dump ps # CoreCLR
kubectl exec <pod> -- sh -c 'ps aux | grep myapp' # NativeAOT
# Collect dump
kubectl exec <pod> -- dotnet-dump collect -p <pid> --output /dumps/myapp.dmp
# Copy dump out of the pod
kubectl cp <pod>:/dumps/myapp.dmp ./myapp.dmpDeployment-Level Configuration
To apply dump collection to all pods in a Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
template:
spec:
containers:
- name: myapp
image: myapp:latest
securityContext:
capabilities:
add: ["SYS_PTRACE"]
env:
- name: DOTNET_DbgEnableMiniDump
value: "1"
- name: DOTNET_DbgMiniDumpType
value: "4"
- name: DOTNET_DbgMiniDumpName
value: "/dumps/%e_%p_%t.dmp"
volumeMounts:
- name: dumps
mountPath: /dumps
volumes:
- name: dumps
emptyDir:
sizeLimit: 5GiVerification
Docker:
# Check env vars inside the container
docker exec <container> env | grep DOTNET_Dbg
# Check dump directory exists and is writable
docker exec <container> ls -la /dumps/
# Check createdump is available (NativeAOT)
docker exec <container> ls -la /app/createdump 2>/dev/null || echo "createdump not co-located"
# After a crash, check for dump files
docker exec <container> sh -c 'ls -la /dumps/*.dmp' 2>/dev/null
# Or from the host via volume mount:
ls -la /tmp/dumps/*.dmpKubernetes:
# Check env vars
kubectl exec <pod> -- env | grep DOTNET_Dbg
# Check dump directory
kubectl exec <pod> -- ls -la /dumps/
# After a crash, list dumps
kubectl exec <pod> -- sh -c 'ls -la /dumps/*.dmp' 2>/dev/null
# Copy dumps out for inspection
kubectl cp <pod>:/dumps/ ./dumps/Container Considerations
Non-Root Users
If your container runs as a non-root user, ensure the dump directory is writable:
RUN mkdir -p /dumps && chown -R app:app /dumps
USER appFor Kubernetes, use an init container or securityContext.fsGroup:
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 1000 # matches the app user's groupWhen using runAsNonRoot: true, the dump directory must be writable by the non-root user. Use fsGroup to grant group write access to the mounted volume, or set permissions in the Dockerfile.
Alpine / musl-Based Images
createdump, dotnet-dump, and CoreCLR automatic crash dumps all work on the supported .NET Alpine images. No special configuration is needed beyond the standard setup described above.
SELinux / AppArmor
On hosts with SELinux or AppArmor, SYS_PTRACE alone may not be sufficient:
- SELinux: The container may need
--security-opt label=disableor an appropriate SELinux policy allowing ptrace - AppArmor: Use
--security-opt apparmor=unconfinedfor debugging, or create a custom profile that allows ptrace
⚠️ Disabling security modules is acceptable for debugging but should not be used in production.
Troubleshooting
| Problem | Cause | Fix |
|---|---|---|
dotnet-dump collect fails with "permission denied" | Missing SYS_PTRACE capability | Add SYS_PTRACE to securityContext / cap_add |
| Dump file not created on crash | Dump directory doesn't exist | Ensure /dumps directory exists in the image or init container |
| Core dump goes to wrong location | Host core_pattern overrides container | Configure core_pattern on the host or use --privileged |
| Dump file is 0 bytes | Disk space exhausted | Increase emptyDir.sizeLimit or PVC size |
createdump not found in container | Minimal runtime image | For CoreCLR: use dotnet-dump collect instead. For NativeAOT: copy createdump from the runtime image (see NativeAOT in Docker section) or use the full SDK image |
CoreCLR Crash Dump Collection
| Need | Tool | Platforms |
|---|---|---|
| Automatic dump on crash | DOTNET_DbgEnableMiniDump env vars | All |
| On-demand from running process | dotnet-dump collect (recommended) | All |
| On-demand via OS tools | gcore (Linux) | Linux |
Automatic Crash Dumps (All Platforms)
CoreCLR has built-in crash dump support via environment variables. Set these before launching the app:
# Enable crash dumps (required)
export DOTNET_DbgEnableMiniDump=1
# Dump type: 1=Mini, 2=Heap, 3=Triage, 4=Full
# Use 4 (Full) for maximum diagnostic value, 1 (Mini) for smaller files
export DOTNET_DbgMiniDumpType=4
# Output path — supports format specifiers (.NET 7+):
# %p = PID, %e = process name, %h = hostname, %t = timestamp
export DOTNET_DbgMiniDumpName=/tmp/dumps/%e_%p_%t.dmp
# Optional: generate a JSON crash report alongside the dump
export DOTNET_EnableCrashReport=1
# Optional: diagnostics if dump creation itself fails
export DOTNET_CreateDumpDiagnostics=1On Windows (PowerShell):
$env:DOTNET_DbgEnableMiniDump = "1"
$env:DOTNET_DbgMiniDumpType = "4"
$env:DOTNET_DbgMiniDumpName = "C:\dumps\%e_%p_%t.dmp"
$env:DOTNET_EnableCrashReport = "1"Dump Type Reference
| Value | Type | Size | Use When |
|---|---|---|---|
| 1 | Mini | Small | Stack traces only, minimal disk usage |
| 2 | Heap | Large | Need to inspect managed heap objects |
| 3 | Triage | Small | The same as mini, but redacts known file paths |
| 4 | Full | Largest | Full process memory, maximum diagnostic value |
Important Notes
- The dump output directory must exist before the crash — CoreCLR will not create it.
- Format specifiers (
%p,%e,%h,%t) require .NET 7+. On .NET 6, use a literal path. - The legacy
COMPlus_prefix (e.g.,COMPlus_DbgEnableMiniDump) still works butDOTNET_is preferred for .NET 6+. - Single-file published apps only support full dumps (
DOTNET_DbgMiniDumpType=4), same as NativeAOT.
On-Demand Dump Collection
Using dotnet-dump (Recommended)
# Install (one-time, requires .NET SDK)
dotnet tool install -g dotnet-dump
# Without the SDK, download directly from https://github.com/dotnet/diagnostics/releases
# List .NET processes
dotnet-dump ps
# Collect a dump from a running process
dotnet-dump collect -p <pid>
# Specify dump type and output path
dotnet-dump collect -p <pid> --type Full --output /tmp/dumps/myapp.dmpSupported `--type` values: Full, Heap, Mini
Using gcore (Linux Only)
# Requires gdb installed
gcore -o /tmp/dumps/myapp <pid>
# Produces /tmp/dumps/myapp.<pid>Verification
After enabling crash dumps, verify the configuration:
# Check env vars are set
env | grep DOTNET_Dbg
env | grep DOTNET_EnableCrashReport
# Ensure dump directory exists and is writable
ls -la /tmp/dumps/
# After a crash, check for dump files
ls -la /tmp/dumps/*.dmpNativeAOT Crash Dump Collection
| Need | Tool | Platforms |
|---|---|---|
| Automatic dump on crash (preferred) | OS-level core dumps (ulimit, core_pattern, WER) | All |
| Automatic dump on crash (alternative) | createdump + DOTNET_DbgEnableMiniDump env vars | All |
| On-demand from running process | gcore (Linux), lldb (macOS), procdump (Windows) | Per-platform |
NativeAOT applications are native executables. Since NativeAOT only supports full dumps, OS-level core dump mechanisms are the simplest approach — no extra tooling to copy or configure.
Note: NativeAOT only supports full dumps.DOTNET_DbgMiniDumpTypemust be set to4(Full).
OS-Level Core Dumps (Preferred)
Linux
Option A: Direct core dumps (simplest)
# Enable core dumps for the current shell session
ulimit -c unlimited
# Set the core dump output pattern (system-wide, requires root)
echo '/tmp/dumps/core.%e.%p.%t' | sudo tee /proc/sys/kernel/core_pattern
# Make persistent across reboots — add to /etc/sysctl.conf:
# kernel.core_pattern = /tmp/dumps/core.%e.%p.%t
# Ensure dump directory exists
mkdir -p /tmp/dumpsNote:ulimitonly applies to processes started in the current shell session. For an already-running process, use on-demand collection withgcore(see On-Demand Dump Collection below).
Format specifiers for `core_pattern`:
| Spec | Meaning |
|---|---|
%p | PID |
%e | Executable name (first 15 chars) |
%t | Unix timestamp |
%h | Hostname |
%u | UID |
Option B: systemd-coredump (systemd systems)
Many Linux distributions pipe core dumps to systemd-coredump by default. Check:
cat /proc/sys/kernel/core_pattern
# If it shows: |/usr/lib/systemd/systemd-coredump ...
# Then systemd-coredump is already handling dumps.Using coredumpctl:
# List collected dumps
coredumpctl list
# Show details of the most recent dump
coredumpctl info
# Export a dump to a file
coredumpctl dump -o /tmp/dumps/myapp.core
# Filter by executable name
coredumpctl list myapp
coredumpctl dump myapp -o /tmp/dumps/myapp.coreConfigure systemd-coredump storage in /etc/systemd/coredump.conf:
[Coredump]
Storage=external
MaxUse=2G
ProcessSizeMax=8GOn-Demand Dump Collection
# Using gcore (from gdb package)
gcore -o /tmp/dumps/myapp <pid>macOS
Automatic Crash Dumps
# Enable core dumps for the current shell session
ulimit -c unlimited
# Core dumps go to /cores/core.<pid>
# Ensure the directory exists and is writable
sudo mkdir -p /cores
sudo chmod 1777 /cores
# Verify the setting
ulimit -c # Should print "unlimited"Notes:
- macOS also generates
.crashreports in~/Library/Logs/DiagnosticReports/automatically — these are text-based crash logs, not full memory dumps. - On Apple Silicon, core dumps may require SIP (System Integrity Protection) adjustments for certain processes.
Retrieving Dumps from an Already-Crashed Process
If the app has already crashed and core dumps were enabled (ulimit -c unlimited was set):
# Check /cores/ for core dumps
ls -la /cores/core.*
# Check macOS crash reports (always generated, even without ulimit)
ls -la ~/Library/Logs/DiagnosticReports/*.crash
# Or on newer macOS:
ls -la ~/Library/Logs/DiagnosticReports/*.ipsIf core dumps were not enabled before the crash, the core dump is lost. The .crash/.ips report in DiagnosticReports is the only artifact — it contains the stack trace and crash reason but not full memory.
On-Demand Dump Collection
# Using lldb (ships with Xcode command-line tools)
lldb -p <pid> -o "process save-core /tmp/dumps/myapp.core" -o "quit"
# Using gcore if gdb is installed (via Homebrew)
gcore -o /tmp/dumps/myapp <pid>Windows
Automatic Crash Dumps (Windows Error Reporting)
WER is a Windows OS-level mechanism — it uses its own DumpType values (0=Custom, 1=Mini, 2=Full) which are separate from the DOTNET_DbgMiniDumpType environment variable. WER works for any process, including NativeAOT apps without createdump.
Configure via the registry. Run in an elevated PowerShell:
# Enable local dumps for a specific application
$appName = "myapp.exe"
$dumpPath = "C:\dumps"
$regPath = "HKLM:\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\$appName"
New-Item -Path $regPath -Force
New-ItemProperty -Path $regPath -Name "DumpFolder" -Value $dumpPath -PropertyType ExpandString -Force
New-ItemProperty -Path $regPath -Name "DumpCount" -Value 10 -PropertyType DWord -Force
New-ItemProperty -Path $regPath -Name "DumpType" -Value 2 -PropertyType DWord -Force
# DumpType: 0=Custom, 1=Mini, 2=Full
# Ensure dump directory exists
New-Item -Path $dumpPath -ItemType Directory -ForceTo enable for ALL applications (not just one), use the parent key:
$regPath = "HKLM:\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps"
New-Item -Path $regPath -Force
New-ItemProperty -Path $regPath -Name "DumpFolder" -Value "C:\dumps" -PropertyType ExpandString -Force
New-ItemProperty -Path $regPath -Name "DumpType" -Value 2 -PropertyType DWord -ForceOn-Demand Dump Collection
Using procdump (recommended — download from Sysinternals):
# Download procdump (one-time)
Invoke-WebRequest -Uri "https://download.sysinternals.com/files/Procdump.zip" -OutFile "$env:TEMP\Procdump.zip"
Expand-Archive "$env:TEMP\Procdump.zip" -DestinationPath "$env:TEMP\Procdump" -Force
# Capture a full dump
& "$env:TEMP\Procdump\procdump.exe" -ma <pid> C:\dumps\myapp.dmp
# Capture on crash (waits for an unhandled exception)
& "$env:TEMP\Procdump\procdump.exe" -ma -e -w <processname> C:\dumps\myapp.dmpUsing Task Manager: 1. Open Task Manager → Details tab 2. Right-click the process → "Create memory dump file" 3. Note the output path shown in the dialog
Alternative: Using createdump with DOTNET_DbgEnableMiniDump
NativeAOT apps also support the DOTNET_DbgEnableMiniDump environment variables if createdump is available. This gives you the same env-var-based workflow as CoreCLR, but requires copying createdump to the right location.
If createdump is placed next to the application binary:
export DOTNET_DbgEnableMiniDump=1
export DOTNET_DbgMiniDumpType=4
export DOTNET_DbgMiniDumpName="/tmp/dumps/%e_%p_%t.dmp"
export DOTNET_EnableCrashReport=1Note: The%e,%p,%h,%tformat specifiers inDOTNET_DbgMiniDumpNamerequire .NET 7+. On .NET 6, use a literal path instead.
Setup: Copy createdump from the .NET runtime into the same directory as your published NativeAOT binary:
# Linux
cp /usr/share/dotnet/shared/Microsoft.NETCore.App/<version>/createdump ./publish/
# macOS
cp /usr/local/share/dotnet/shared/Microsoft.NETCore.App/<version>/createdump ./publish/
# Windows (PowerShell)
Copy-Item "C:\Program Files\dotnet\shared\Microsoft.NETCore.App\<version>\createdump.exe" .\publish\If the .NET runtime is not installed (fully self-contained deployment), extract createdump from the runtime Docker image or NuGet package:
# Extract from Docker runtime image
docker run --rm -v "$(pwd)/publish:/out" mcr.microsoft.com/dotnet/runtime:10.0 \
sh -c 'cp /usr/share/dotnet/shared/Microsoft.NETCore.App/*/createdump /out/'.NET 11+: DOTNET_DbgCreateDumpToolPath
Starting with .NET 11, you can point to createdump at any location instead of requiring it next to the binary:
export DOTNET_DbgCreateDumpToolPath=/opt/tools/createdump
export DOTNET_DbgEnableMiniDump=1
export DOTNET_DbgMiniDumpType=4
export DOTNET_DbgMiniDumpName="/tmp/dumps/%e_%p_%t.dmp"This is especially useful in containers where you can install createdump once in a shared location.
Verification
When using OS-level core dumps
# Linux — check core_pattern and ulimit
cat /proc/sys/kernel/core_pattern
ulimit -c
# macOS — check ulimit and /cores/
ulimit -c
ls -la /cores/
# Linux (systemd) — check for recent dumps
coredumpctl list --no-pager | tail -5# Windows — check WER registry
Get-ChildItem "HKLM:\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps" -ErrorAction SilentlyContinue
Get-ChildItem "C:\dumps" -ErrorAction SilentlyContinueWhen using createdump + DOTNET_DbgEnableMiniDump
# Verify env vars are set
env | grep DOTNET_Dbg
env | grep DOTNET_EnableCrashReport
# Verify createdump is next to the binary (or at DOTNET_DbgCreateDumpToolPath)
ls -la ./createdump # co-located
# or: ls -la $DOTNET_DbgCreateDumpToolPath # .NET 11+
# Verify dump directory exists
ls -la /tmp/dumps/