dotnet/runtime · error
Problem reading from createdump child_read_pipe: %s (%d)\n
Error message
Problem reading from createdump child_read_pipe: %s (%d)\n
What it means
Emitted by the forked child in the CoreCLR PAL crash-dump path PROCLaunchCreateDump (process.cpp:1527). After fork the child closes the parent-side fds and blocks on read(child_read_pipe) waiting for the parent's single-byte prctl(PR_SET_PTRACER) signal; the read is retried only on EINTR. If bytesRead != 1 (read returned 0 = EOF or a hard error) the child prints this, closes child_write_pipe and exit(-1) BEFORE the g_createdumpCallback / execve branch is ever reached, so no dump is generated by either mechanism.
Source
Thrown at src/coreclr/pal/src/thread/process.cpp:1527
}
return false;
}
else if (childpid == 0)
{
int callbackResult = 0;
close(parent_read_pipe);
close(parent_write_pipe);
// Wait for prctl(PR_SET_PTRACER, childpid) in parent
char buffer;
int bytesRead;
while((bytesRead = read(child_read_pipe, &buffer, 1)) < 0 && errno == EINTR);
close(child_read_pipe);
if (bytesRead != 1)
{
fprintf(stderr, "Problem reading from createdump child_read_pipe: %s (%d)\n", strerror(errno), errno);
close(child_write_pipe);
exit(-1);
}
// Only dup the child's stderr if there is error buffer
if (errorMessageBuffer != nullptr)
{
dup2(child_write_pipe, STDERR_FILENO);
}
if (g_createdumpCallback != nullptr)
{
// Remove the signal handlers inherited from the runtime process
SEHCleanupSignals(true /* isChildProcess */);
// Call the statically linked createdump code
int argc = 0;
while (argv[argc] != nullptr && argc < MAX_ARGV_ENTRIES)
{View on GitHub (pinned to 290d5ab72c)
Solutions
- Enable verbose diagnostics and reproduce: set DOTNET_CreateDumpDiagnostics=1 DOTNET_CreateDumpVerboseDiagnostics=1 to capture what the parent did before it stopped writing.
- Check for external kills during the crash: `dmesg -T | grep -i 'killed process'` (oom-killer) and container runtime OOM events; raise cgroup memory limits.
- Raise the open-files limit (ulimit -n) so the crash path has the fds it needs for the two pipes.
- If PR_SET_PTRACER setup is the culprit (hardened kernel/Yama ptrace_scope), set /proc/sys/kernel/yama/ptrace_scope to 0 or 1, or run as root, to let the parent complete the prctl step.
- Fall back to kernel core dumps: unset DOTNET_DbgEnableMiniDump and configure /proc/sys/kernel/core_pattern, removing the dependency on the in-process fork handshake.
Example fix
# before $ DOTNET_DbgEnableMiniDump=1 ./app # Problem reading from createdump child_read_pipe: Success (0) # parent died (EOF) # after: confirm/relieve the cause of the parent dying $ dmesg -T | grep -i 'killed process' $ ulimit -n 65536 $ DOTNET_DbgEnableMiniDump=1 DOTNET_CreateDumpVerboseDiagnostics=1 ./app
Defensive patterns
Strategy: validation
Validate before calling
# Validate that the parent can complete the prctl handshake on this host before enabling dumps. cat /proc/sys/kernel/yama/ptrace_scope 2>/dev/null | grep -Eq '^[01]$' || echo "WARN: ptrace_scope may block PR_SET_PTRACER" [ "$(ulimit -n)" -ge 1024 ] || ulimit -n 65536 # Ensure the process won't be OOM-killed during crash handling: grep MemAvailable /proc/meminfo DOTNET_DbgEnableMiniDump=1 DOTNET_CreateDumpVerboseDiagnostics=1 "$@"
Prevention
- On hardened kernels, set /proc/sys/kernel/yama/ptrace_scope to 0 or 1 so PR_SET_PTRACER succeeds and the parent reaches the signal write.
- Give the crashing process enough memory/fds to survive through the fork+prctl sequence (cgroup limits, ulimit -n).
- Run the workload as PID 1 (or without an aggressive reaper) so the parent is not externally killed mid-handshake.
- Enable DOTNET_CreateDumpDiagnostics=1 to capture the parent's behavior when the child reports a failed read.
- Keep kernel core_pattern as a fallback dump source independent of the parent/child pipe.
When it happens
Trigger: DOTNET_DbgEnableMiniDump=1 (or a runtime-triggered dump) on the full CoreCLR runtime causes a fork; the child is waiting on child_read_pipe but the parent never wrote the 'S' byte because it died, was killed, or crashed inside the prctl(PR_SET_PTRACER) block (lines 1571-1577) before reaching the write() at line 1580. The child's read then returns EOF.
Common situations: Parent process killed by the OOM killer or a container runtime between fork and the signal write; parent took a second, more fatal signal (e.g. SIGSEGV in the signal handler itself) during prctl setup; pipe fds exhausted/closed prematurely; running under a debugger or tracer that interferes with PR_SET_PTRACER and the parent aborted; very tight memory/fd limits on the crash path.
Related errors
- Problem writing to createdump parent_write_pipe: %s (%d)\n
- Problem launching createdump (may not have execute permissio
- Problem waiting for createdump: waitpid() FAILED result %d w
- Problem writing to createdump parent_write_pipe: %s (%d)\n
- Problem launching createdump (may not have execute permissio
AI-assisted analysis of dotnet/runtime@290d5ab72c (2026-08-06).
Data as JSON: /api/errors/c0a4eee8788abf51.
Report an issue: GitHub.