dotnet/runtime · error

execv(%s) failed: %s\n

Error message

execv(%s) failed: %s\n

What it means

After the forked ParallelSuperPMI child has redirected stdout/stderr it calls execv(argv[0],argv) to become a superpmi worker. execv only returns on failure; if it does, the child prints the target path and strerror(errno) and _exit(1). The parent's StartProcess already returned true (fork succeeded) so the failure surfaces as a worker that dies immediately.

Source

Thrown at src/coreclr/tools/superpmi/superpmi/parallelsuperpmi.cpp:233

            fprintf(stderr, "dup2(stdout) failed: %s\n", strerror(errno));
            _exit(1);
        }
        if (dup2(hStdError, STDERR_FILENO) == -1)
        {
            fprintf(stderr, "dup2(stderr) failed: %s\n", strerror(errno));
            _exit(1);
        }

        // Close the original fds now that they are duplicated to STDOUT/STDERR.
        // The O_CLOEXEC on the parent's open() handles the sibling worker fds.
        if (hStdOutput != STDOUT_FILENO)
            close(hStdOutput);
        if (hStdError != STDERR_FILENO)
            close(hStdError);

        execv(argv[0], argv);
        // If execv returns, it failed.
        fprintf(stderr, "execv(%s) failed: %s\n", argv[0], strerror(errno));
        _exit(1);
    }

    // Parent process: free argv and return.
    for (int i = 0; i < argc; i++)
        delete[] argv[i];
    delete[] argv;
    return true;
}

#endif // TARGET_UNIX

void ReadMCLToArray(char* mclFilename, int** arr, int* count)
{
    *count     = 0;
    *arr       = nullptr;
    char* buff = nullptr;

View on GitHub (pinned to 60108ba66e)

Solutions

  1. Pass an absolute path to the worker executable as argv[0], or ensure it is on PATH for the spawned shell.
  2. Confirm the worker file exists and is executable (chmod +x; ls -l) and matches the host arch (file <worker>).
  3. Rebuild SuperPMI so both orchestrator and worker binaries are present in artifacts/bin.
  4. Run parallelsuperpmi with the same cwd/PATH used at build time, or set -executablePath to the artifacts bin dir.
Defensive patterns

Strategy: validation

Validate before calling

// Validate the worker executable is runnable before forking.
#include <unistd.h>
#include <sys/stat.h>
static bool WorkerExecutable(const char* path) {
    struct stat st;
    if (stat(path, &st) != 0) return false;       // ENOENT
    if (!S_ISREG(st.st_mode)) return false;       // not a regular file
    if (access(path, X_OK) != 0) return false;    // not executable
    return true;
}

Prevention

When it happens

Trigger: argv[0] does not exist (ENOENT), is not executable or permissions deny (EACCES), wrong ELF/arch (ENOEXEC), path too long (ENAMETOOLONG), or the binary is a directory. The parsed command line's first token is the worker executable.

Common situations: Running parallelsuperpmi without the worker (superpmi/mcs) on PATH or with a relative path resolved against the wrong cwd; a build that produced the orchestrator but not the worker; cross-arch copy; stale SuperPMIShimPath / worker path; executable bit lost during packaging.

Related errors


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