Claude Cursor GitHub Copilot Skill

dump-collect

Configure and collect crash dumps for modern .NET applications. USE FOR: enabling automatic crash dumps for CoreCLR or NativeAOT, capturing dumps from running .NET processes, setting up dump collection in Docker or Kubernetes, using dotnet-dump collect or createdump. DO NOT USE F

LLM Mart · 0 points · 23 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download dotnet-skills-plugins_dotnet-diag_skills_dump-collect-98f8485.zip · 10 KB
Part of dotnet/skills — 119 skills

Install

skills CLI npx skills add https://github.com/dotnet/skills/tree/main/plugins/dotnet-diag/skills/dump-collect
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install dotnet-skills@llmmart
Git git clone https://github.com/dotnet/skills.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole dotnet/skills collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

.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 lldb for 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" -Quiet

From 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.
Files (skills)
  • references
    • container-dumps.md 11.2 KB
      # 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`, `%t` format specifiers in `DOTNET_DbgMiniDumpName` require .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:
      
      ```bash
      # docker run
      docker run --cap-add=SYS_PTRACE -v /tmp/dumps:/dumps myapp
      
      # docker compose
      ```
      
      ```yaml
      # 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`:
      
      ```bash
      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 \
        myapp
      ```
      
      Or in the Dockerfile (baked into the image):
      
      ```dockerfile
      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:**
      
      ```bash
      docker run --cap-add=SYS_PTRACE \
        --ulimit core=-1 \
        -v /tmp/dumps:/dumps \
        myapp
      ```
      
      **Note:** 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:
      
      ```bash
      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:
      
      ```dockerfile
      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:
      
      ```dockerfile
      ENV DOTNET_DbgCreateDumpToolPath=/opt/tools/createdump
      ENV DOTNET_DbgEnableMiniDump=1
      ENV DOTNET_DbgMiniDumpType=4
      ENV DOTNET_DbgMiniDumpName="/dumps/%e_%p_%t.dmp"
      ```
      
      Run with:
      ```bash
      docker run --cap-add=SYS_PTRACE \
        -v /tmp/dumps:/dumps \
        myapp
      ```
      
      ### On-Demand Collection in Docker
      
      ```bash
      # 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.dmp
      ```
      
      ## Kubernetes
      
      ### Pod Spec for CoreCLR
      
      ```yaml
      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 size
      ```
      
      ### Pod Spec for NativeAOT
      
      **Preferred: OS-level core dumps** (simplest — no extra tooling needed):
      
      ```yaml
      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: 10Gi
      ```
      
      **Alternative: Use createdump** (bundled in the image next to the app, or via `DOTNET_DbgCreateDumpToolPath` on .NET 11+):
      
      ```yaml
      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: 5Gi
      ```
      
      ### Using a Persistent Volume for Dumps
      
      For production, use a PersistentVolumeClaim instead of `emptyDir` so dumps survive pod restarts:
      
      ```yaml
      volumes:
        - name: dumps
          persistentVolumeClaim:
            claimName: dump-storage
      
      ---
      apiVersion: v1
      kind: PersistentVolumeClaim
      metadata:
        name: dump-storage
      spec:
        accessModes: ["ReadWriteOnce"]
        resources:
          requests:
            storage: 20Gi
      ```
      
      ### On-Demand Collection in Kubernetes
      
      ```bash
      # 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.dmp
      ```
      
      ### Deployment-Level Configuration
      
      To apply dump collection to all pods in a Deployment:
      
      ```yaml
      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: 5Gi
      ```
      
      ## Verification
      
      **Docker:**
      
      ```bash
      # 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/*.dmp
      ```
      
      **Kubernetes:**
      
      ```bash
      # 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:
      
      ```dockerfile
      RUN mkdir -p /dumps && chown -R app:app /dumps
      USER app
      ```
      
      For Kubernetes, use an init container or `securityContext.fsGroup`:
      
      ```yaml
      securityContext:
        runAsNonRoot: true
        runAsUser: 1000
        fsGroup: 1000    # matches the app user's group
      ```
      
      When 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=disable` or an appropriate SELinux policy allowing ptrace
      - **AppArmor**: Use `--security-opt apparmor=unconfined` for 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-dumps.md 2.9 KB
      # 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:
      
      ```bash
      # 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=1
      ```
      
      **On Windows (PowerShell):**
      ```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 but `DOTNET_` 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)
      
      ```bash
      # 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.dmp
      ```
      
      **Supported `--type` values:** `Full`, `Heap`, `Mini`
      
      ### Using gcore (Linux Only)
      
      ```bash
      # Requires gdb installed
      gcore -o /tmp/dumps/myapp <pid>
      # Produces /tmp/dumps/myapp.<pid>
      ```
      
      ## Verification
      
      After enabling crash dumps, verify the configuration:
      
      ```bash
      # 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/*.dmp
      ```
      
    • nativeaot-dumps.md 8.6 KB
      # NativeAOT 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_DbgMiniDumpType` must be set to `4` (Full).
      
      ## OS-Level Core Dumps (Preferred)
      
      ### Linux
      
      **Option A: Direct core dumps (simplest)**
      
      ```bash
      # 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/dumps
      ```
      
      > **Note:** `ulimit` only applies to processes started in the current shell session. For an already-running process, use on-demand collection with `gcore` (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:
      
      ```bash
      cat /proc/sys/kernel/core_pattern
      # If it shows: |/usr/lib/systemd/systemd-coredump ...
      # Then systemd-coredump is already handling dumps.
      ```
      
      Using `coredumpctl`:
      
      ```bash
      # 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.core
      ```
      
      Configure systemd-coredump storage in `/etc/systemd/coredump.conf`:
      ```ini
      [Coredump]
      Storage=external
      MaxUse=2G
      ProcessSizeMax=8G
      ```
      
      ### On-Demand Dump Collection
      
      ```bash
      # Using gcore (from gdb package)
      gcore -o /tmp/dumps/myapp <pid>
      ```
      
      ## macOS
      
      ### Automatic Crash Dumps
      
      ```bash
      # 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 `.crash` reports 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):
      
      ```bash
      # 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/*.ips
      ```
      
      If 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
      
      ```bash
      # 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**:
      
      ```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 -Force
      ```
      
      **To enable for ALL applications** (not just one), use the parent key:
      ```powershell
      $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 -Force
      ```
      
      ### On-Demand Dump Collection
      
      **Using procdump (recommended — download from Sysinternals):**
      
      ```powershell
      # 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.dmp
      ```
      
      **Using 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**:
      
      ```bash
      export DOTNET_DbgEnableMiniDump=1
      export DOTNET_DbgMiniDumpType=4
      export DOTNET_DbgMiniDumpName="/tmp/dumps/%e_%p_%t.dmp"
      export DOTNET_EnableCrashReport=1
      ```
      
      > **Note:** The `%e`, `%p`, `%h`, `%t` format specifiers in `DOTNET_DbgMiniDumpName` require .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:
      
      ```bash
      # 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:
      
      ```bash
      # 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:
      
      ```bash
      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
      
      ```bash
      # 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
      ```
      
      ```powershell
      # Windows — check WER registry
      Get-ChildItem "HKLM:\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps" -ErrorAction SilentlyContinue
      Get-ChildItem "C:\dumps" -ErrorAction SilentlyContinue
      ```
      
      ### When using createdump + DOTNET_DbgEnableMiniDump
      
      ```bash
      # 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/
      ```
      
  • SKILL.md 4.2 KB
    ---
    name: dump-collect
    description: "Configure and collect crash dumps for modern .NET applications. USE FOR: enabling automatic crash dumps for CoreCLR or NativeAOT, capturing dumps from running .NET processes, setting up dump collection in Docker or Kubernetes, using dotnet-dump collect or createdump. DO NOT USE FOR: analyzing or debugging dumps, post-mortem investigation with lldb/windbg/dotnet-dump analyze, profiling or tracing, or for .NET Framework processes."
    license: MIT
    ---
    
    # .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 `lldb` for 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):**
    ```bash
    # 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):**
    ```powershell
    # 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" -Quiet
    ```
    
    **From a running process (Linux):**
    ```bash
    # 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):**
    ```bash
    # 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):**
    ```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.
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related