{"record":{"id":"9259436de4fab075","repo":"dotnet/runtime","slug":"problem-writing-to-createdump-parent-write-pipe-925943","errorCode":null,"errorMessage":"Problem writing to createdump parent_write_pipe: %s (%d)\\n","messagePattern":"Problem writing to createdump parent_write_pipe: (.+?) \\((.+?)\\)\\\\n","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/coreclr/pal/src/thread/process.cpp","lineNumber":1585,"sourceCode":"        close(child_read_pipe);\n        close(child_write_pipe);\n#if HAVE_PRCTL_H && HAVE_PR_SET_PTRACER\n        // Gives the child process permission to use /proc/<pid>/mem and ptrace\n        if (prctl(PR_SET_PTRACER, childpid, 0, 0, 0) == -1)\n        {\n            // Ignore any error because on some CentOS and OpenSUSE distros, it isn't\n            // supported but createdump works just fine.\n            ERROR(\"PROCCreateCrashDump: prctl() FAILED %s (%d)\\n\", strerror(errno), errno);\n        }\n#endif // HAVE_PRCTL_H && HAVE_PR_SET_PTRACER\n        // Signal child that prctl(PR_SET_PTRACER, childpid) is done\n        int bytesWritten;\n        while((bytesWritten = write(parent_write_pipe, \"S\", 1)) < 0 && errno == EINTR);\n        close(parent_write_pipe);\n\n        if (bytesWritten != 1)\n        {\n            fprintf(stderr, \"Problem writing to createdump parent_write_pipe: %s (%d)\\n\", strerror(errno), errno);\n            close(parent_read_pipe);\n            if (errorMessageBuffer != nullptr)\n            {\n                errorMessageBuffer[0] = 0;\n            }\n            return false;\n        }\n\n        // Read createdump's stderr messages (if any)\n        if (errorMessageBuffer != nullptr)\n        {\n            // Read createdump's stderr\n            int bytesRead = 0;\n            int count = 0;\n            while ((count = read(parent_read_pipe, errorMessageBuffer + bytesRead, cbErrorMessageBuffer - bytesRead)) > 0)\n            {\n                bytesRead += count;\n            }","sourceCodeStart":1567,"sourceCodeEnd":1603,"githubUrl":"https://github.com/dotnet/runtime/blob/60108ba66eb7d1d12f595480091b4ad80a24b172/src/coreclr/pal/src/thread/process.cpp#L1567-L1603","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["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.","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.","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.","On fd exhaustion, raise the process ulimit (ulimit -n) and fix leaks so the write to the pipe can succeed."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Before relying on in-crash dumps, verify the environment can ptrace the parent.\n#include <sys/prctl.h>\n#include <errno.h>\n#include <string.h>\nstatic bool CanPtraceChildren() {\n#ifdef PR_SET_PTRACER\n    // best-effort; a zero return means ptrace_scope allows it\n    int v = -1;\n    FILE* f = fopen(\"/proc/sys/kernel/yama/ptrace_scope\", \"r\");\n    if (f) { if (fscanf(f, \"%d\", &v) != 1) v = -1; fclose(f); }\n    return v == 0 || v == -1; // -1 => no Yama (no restriction)\n#else\n    return true;\n#endif\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Run .NET crash-dump-dependent workloads on hosts where kernel.yama.ptrace_scope is 0 or grant the container CAP_SYS_PTRACE.","Do not install SIGCHLD handlers that reap unrelated children; let the runtime own the createdump child.","Validate container seccomp/AppArmor profiles do not block prctl/ptrace before enabling DOTNET_DbgEnableMiniDump.","For production diagnostics prefer dotnet-dump collect on a live process over in-crash createdump when ptrace is restricted."],"tags":["coreclr","createdump","crash-dump","pipes","ptrace","linux","diagnostics"],"backgroundTag":null,"analyzedSha":"60108ba66eb7d1d12f595480091b4ad80a24b172","analyzedAt":"2026-08-10T18:54:11.478Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}