简体   繁体   English

waitpid()提供错误的退出代码

[英]waitpid() gives incorrect exit code

I've got a function for starting a process, and then returning the stdout and exit code. 我有一个用于启动进程,然后返回标准输出和退出代码的函数。 However I've noticed that it claims that every process returns the exit code of 1. I control the executable being invoked and I had it print to stdout the exit code, so I've confirmed that when it "failed", it in fact returned 0 from main . 但是,我注意到它声称每个进程都返回退出代码1。我控制了正在执行的可执行文件,并打印了该输出以标出退出代码,因此我已经确认,当它“失败”时,实​​际上从main返回0。 I also invoked the executable directly form the shell and confirmed the expected stdout and exit code (0). 我还直接从外壳程序调用了可执行文件,并确认了预期的标准输出和退出代码(0)。 So the fault must lie on the side of the caller. 因此,故障必须出在呼叫者一方。 I've also confirmed that WIFEXITED doesn't return false- it returns true as if the child had exited normally (which it did). 我还确认了WIFEXITED不会返回false-就像孩子正常退出一样返回true。

This code worked fine before I needed to capture stdout, so it must have something to do with that. 在我需要捕获stdout之前,这段代码可以正常工作,因此它必须与此有关。 I tried looking into the "Child has already terminated" jobby, but that's not occurring in this case- waitpid() behaves exactly like I'd expect and just doesn't care that the child might have already terminated whilst I was nomming up the stdout. 我尝试查看“孩子已经终止”作业,但是在这种情况下没有发生-waitpid()的行为与我期望的完全一样,只是不在乎孩子在我命名时可能已经终止了。标准输出。

#include <unistd.h>    
#include <sys/types.h>    
#include <sys/wait.h> 
#include <iostream>

Wide::Driver::ProcessResult Wide::Driver::StartAndWaitForProcess(std::string name, std::vector<std::string> args, Util::optional<unsigned> timeout) {
    int filedes[2];
    pipe(filedes);


    pid_t pid = fork();

    if (pid == 0) {
        while ((dup2(filedes[1], STDOUT_FILENO) == -1) && (errno == EINTR)) {}
        freopen("/dev/null", "rw", stdin);
        freopen("/dev/null", "rw", stderr);
        //close(filedes[0]);

        std::vector<const char*> cargs;

        cargs.push_back(name.c_str());

        for (auto&& arg : args)

            cargs.push_back(arg.c_str());

        cargs.push_back(nullptr);

        execv(name.c_str(), const_cast<char* const*>(&cargs[0]));

    }
    std::string std_out;
    close(filedes[1]);
    char buffer[4096];
    while (1) {
        ssize_t count = read(filedes[0], buffer, sizeof(buffer));
        if (count == -1) {
            if (errno == EINTR) {
                continue;
            } else {
                perror("read");
                exit(1);
            }
        } else if (count == 0) {
            break;
        } else {
            std_out += std::string(buffer, buffer + count);
        }
    }
    close(filedes[0]);

    int status;
    ProcessResult result;
    result.std_out = std_out;
    waitpid(pid, &status, 0);

    if (!WIFEXITED(status))

        result.exitcode = 1;

    else {
        result.exitcode = WEXITSTATUS(status);
        if (result.exitcode != 0) {
            std::cout << name << " failed with code " << result.exitcode << "\n";
            std::cout << "stdout: " << result.std_out;
        }
    }
    return result;
}

Why on earth is waitpid() giving me this strange result and how can I fix it? 为什么地球上的waitpid()会给我这个奇怪的结果,我该如何解决呢?

I've confirmed in IRC that it is an LLVM issue. 我已经在IRC中确认这是LLVM问题。 The exit code for the process I printed out is what I returned from main - a static destructor or other such code can still run and call exit(1) . 我打印出的进程的退出代码是我从main返回的-静态析构函数或其他此类代码仍然可以运行并调用exit(1) This is caused by redirecting stderr- so basically you can't get the error, since if you don't redirect stderr you don't see the problem. 这是由重定向stderr引起的-因此,基本上,您不会收到错误,因为如果不重定向stderr,则不会看到问题。 So if you execute from the shell, since stderr is not redirected, it's all good. 因此,如果您从外壳执行,由于不会重定向stderr,因此一切都很好。

Therefore, despite the shell and my own return code agreeing, the process was in fact returning the exit code of 1. 因此,尽管外壳程序和我自己的返回码一致,但实际上该过程返回的是退出码1。

Apparently the issue is resolved in trunk, or should be, but I am still using 3.6. 显然,该问题已在树干中解决,或者应该已经解决,但我仍在使用3.6。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM