dotnet/runtime · error

Problem writing to createdump parent_write_pipe

Error message

Problem writing to createdump parent_write_pipe: %s (%d)\n

What it means

Printed by the .NET CoreCLR PAL crash-dump path after the parent process forks a createdump child and finishes prctl(PR_SET_PTRACER). The parent writes a single 'S' byte to parent_write_pipe to release the child; if that write does not return exactly 1 byte the dump handshake is aborted and PROCCreateCrashDump returns false. The errno is reported so the OS-level cause (typically EPIPE/EAGAIN) is visible. This is part of the out-of-process createdump diagnostic pipeline used during native crashes.

Solutions

  1. Run the application in a container/host that permits ptrace of the parent by createdump: disable or raise kernel.yama.ptrace_scope (sysctl kernel.yama.ptrace_scope=0) or grant CAP_SYS_PTRACE to the container.
  2. Check dmesg/journal for the createdump child's own error (it prints the real cause, e.g. permission denied reading /proc/<pid>/mem) and address that first.
  3. If dump generation is not required, disable it at startup with DOTNETHOST_DiagnosticPorts= or by not configuring DOTNET_DbgEnableMiniDump, so the crashing path does not fork createdump.
  4. On fd exhaustion, raise the process ulimit (ulimit -n) and fix leaks so the write to the pipe can succeed.
Defensive patterns

Strategy: validation

Validate before calling

// Before relying on in-crash dumps, verify the environment can ptrace the parent.
#include <sys/prctl.h>
#include <errno.h>
#include <string.h>
static bool CanPtraceChildren() {
#ifdef PR_SET_PTRACER
    // best-effort; a zero return means ptrace_scope allows it
    int v = -1;
    FILE* f = fopen("/proc/sys/kernel/yama/ptrace_scope", "r");
    if (f) { if (fscanf(f, "%d", &v) != 1) v = -1; fclose(f); }
    return v == 0 || v == -1; // -1 => no Yama (no restriction)
#else
    return true;
#endif
}

Prevention

When it happens

Trigger: Reached only on the parent side of a forked createdump invocation, after prctl(PR_SET_PTRACER) completes. Fires when write(parent_write_pipe,"S",1) returns != 1 (other than retried EINTR), e.g. the child already died/closed the read end before reading the signal byte, or the process exhausted file descriptors/pipe buffers.

Common situations: A crash occurs while the createdump child cannot ptrace the parent (Yama ptrace_scope, container without CAP_SYS_PTRACE), so the child aborts and closes the pipe before the parent writes. Also seen when the crashing process is already out of fds, or under heavy signal-load where the child exits early. Container/k8s pods that restrict ptrace are a frequent host.

Related errors


AI-assisted analysis of dotnet/runtime@60108ba66e (2026-08-10). Data as JSON: /api/errors/9259436de4fab075. Report an issue: GitHub.

Appendix: source

Thrown at src/coreclr/pal/src/thread/process.cpp:1585

        close(child_read_pipe);
        close(child_write_pipe);
#if HAVE_PRCTL_H && HAVE_PR_SET_PTRACER
        // Gives the child process permission to use /proc/<pid>/mem and ptrace
        if (prctl(PR_SET_PTRACER, childpid, 0, 0, 0) == -1)
        {
            // Ignore any error because on some CentOS and OpenSUSE distros, it isn't
            // supported but createdump works just fine.
            ERROR("PROCCreateCrashDump: prctl() FAILED %s (%d)\n", strerror(errno), errno);
        }
#endif // HAVE_PRCTL_H && HAVE_PR_SET_PTRACER
        // Signal child that prctl(PR_SET_PTRACER, childpid) is done
        int bytesWritten;
        while((bytesWritten = write(parent_write_pipe, "S", 1)) < 0 && errno == EINTR);
        close(parent_write_pipe);

        if (bytesWritten != 1)
        {
            fprintf(stderr, "Problem writing to createdump parent_write_pipe: %s (%d)\n", strerror(errno), errno);
            close(parent_read_pipe);
            if (errorMessageBuffer != nullptr)
            {
                errorMessageBuffer[0] = 0;
            }
            return false;
        }

        // Read createdump's stderr messages (if any)
        if (errorMessageBuffer != nullptr)
        {
            // Read createdump's stderr
            int bytesRead = 0;
            int count = 0;
            while ((count = read(parent_read_pipe, errorMessageBuffer + bytesRead, cbErrorMessageBuffer - bytesRead)) > 0)
            {
                bytesRead += count;
            }

View on GitHub (pinned to 60108ba66e)