dotnet/runtime · error

Problem waiting for createdump: waitpid() FAILED result %d w

Error message

Problem waiting for createdump: waitpid() FAILED result %d wstatus %08x errno %s (%d)\n

What it means

Emitted by the NativeAOT parent in CreateCrashDump (PalCreateDump.cpp:336) when waitpid(childpid, &wstatus, 0) returns a value other than childpid. The PAL does not loop on EINTR here, so a single interrupted waitpid surfaces as a hard failure (return false). The dominant cause is ECHILD: the createdump child was already reaped by something else, so the runtime's waitpid finds no child to wait for.

Source

Thrown at src/coreclr/nativeaot/Runtime/unix/PalCreateDump.cpp:336

            int count = 0;
            while ((count = read(parent_read_pipe, errorMessageBuffer + bytesRead, cbErrorMessageBuffer - bytesRead)) > 0)
            {
                bytesRead += count;
            }
            errorMessageBuffer[bytesRead] = 0;
            if (bytesRead > 0)
            {
                fputs(errorMessageBuffer, stderr);
            }
        }
        close(parent_read_pipe);

        // Parent waits until the child process is done
        int wstatus = 0;
        int result = waitpid(childpid, &wstatus, 0);
        if (result != childpid)
        {
            fprintf(stderr, "Problem waiting for createdump: waitpid() FAILED result %d wstatus %08x errno %s (%d)\n",
                result, wstatus, strerror(errno), errno);
            return false;
        }
        else
        {
#ifdef _DEBUG
            fprintf(stderr, "waitpid() returned successfully (wstatus %08x) WEXITSTATUS %x WTERMSIG %x\n", wstatus, WEXITSTATUS(wstatus), WTERMSIG(wstatus));
#endif
            return !WIFEXITED(wstatus) || WEXITSTATUS(wstatus) == 0;
        }
    }
    return true;
}

#endif // !defined(HOST_MACCATALYST) && !defined(HOST_IOS) && !defined(HOST_TVOS)

// Helper function to prevent compiler from optimizing away a variable
#if defined(__llvm__)

View on GitHub (pinned to 290d5ab72c)

Solutions

  1. If a container init/PID-1 reaper is stealing the child, disable child reaping for this process or run the app as PID 1 without a reaper (or use a reaper that only reaps truly orphaned children).
  2. Run createdump indirectly through the OS core pattern instead: unset DOTNET_DbgEnableMiniDump and configure /proc/sys/kernel/core_pattern to invoke createdump so the kernel owns the wait.
  3. Inspect whether any embedded native library installs a global SIGCHLD handler and have it not reap unknown children.
  4. Reproduce with DOTNET_CreateDumpVerboseDiagnostics=1 to confirm whether createdump actually completed (the waitpid failure may be a false negative).
  5. If unavoidable in the deployment, accept that dumps may be unreliable here and capture coredumps at the OS level as the primary mechanism.

Example fix

# before: a PID-1 reaper steals the createdump child
$ docker run --init myapp   # tini reaps children -> waitpid() FAILED ECHILD

# after: let the runtime own its child, or use the kernel core pattern
$ docker run myapp                     # no --init reaper
$ echo '|/usr/share/dotnet/createdump %p %e' > /proc/sys/kernel/core_pattern
$ ulimit -c unlimited && ./app
Defensive patterns

Strategy: validation

Validate before calling

# Detect a child-reaping PID-1 / SIGCHLD handler that would break waitpid.
ps -o pid,comm -p 1 | grep -Eqi 'tini|dumb-init|init|systemd' && echo "WARN: PID 1 may reap createdump child"
# If reaping is present, plan to use the kernel core pattern instead:
[ -w /proc/sys/kernel/core_pattern ] && echo '|/usr/share/dotnet/createdump %p %e' > /proc/sys/kernel/core_pattern || echo "core_pattern not writable; avoid DOTNET_DbgEnableMiniDump here"

Prevention

When it happens

Trigger: DOTNET_DbgEnableMiniDump=1 crash path reaches the parent's waitpid but another agent reaped the forked createdump child first, or waitpid was interrupted by an unblocked signal (EINTR) and not retried. result != childpid triggers the fprintf and returns false even though createdump may have run.

Common situations: A service supervisor or PID-1 init (tini/dumb-init, systemd, Kubernetes pause) configured to reap all children stole the child exit status; a SIGCHLD handler in a native dependency called wait/waitpid globally; signal delivery (EINTR) during a heavily signal-loaded crash; on some libc/glibc versions a race with thread library helper threads.

Related errors


AI-assisted analysis of dotnet/runtime@290d5ab72c (2026-08-06). Data as JSON: /api/errors/263bb6578a404769. Report an issue: GitHub.