1

我想在我的 C++ 程序中分析 strace 的输出。从我的应用程序启动/bin/strace ps时,我从 ps 获得输出,但不是从 strace 获得输出,并且 strace 输出被打印到 stdout(我的终端)。我使用使用管道和重定向流的标准技术。

这是我的来源:

#include <stdlib.h> 
#include <iostream> 
#include <sys/types.h> 
#include <sys/wait.h> 
#include <unistd.h> 
#include <fcntl.h>
int main(){
    char *const parmList[] = {"/bin/strace", "ps", NULL};
    int pipes[2];
    pipe(pipes);
    pid_t child = fork();
    if(child == 0){
        close(pipes[0]);
        dup2(pipes[1],1);
        execv(parmList[0], parmList);
    }
    else{
        int status;
        wait(&status);

        fcntl(pipes[0], F_SETFL, O_NONBLOCK | O_ASYNC); 
        char buf[128] = {0}; 
        ssize_t bytesRead; 
        std::string stdOutBuf; 
        while(1) {
            bytesRead = read(pipes[0], buf, sizeof(buf)-1);
            if (bytesRead <= 0)
                break;
            buf[bytesRead] = 0;
            stdOutBuf += buf;
        } 
        std::cout << "<stdout>\n" << stdOutBuf << "\n</stdout>" << std::endl; 
    }

    close(pipes[0]);
    close(pipes[1]);

    return 0;
 }

如何在我的程序中获得 strace 的输出?

4

1 回答 1

1

strace 写入stderrnot to stdout,如果您只想捕获 strace 输出,只需使用 stderr 而不是 stdout

像这样改变dup2线

     dup2(pipes[1],2);

如果您想要组合 strace 和 ps 输出,请执行以下操作:

    dup2(pipes[1],1);
    dup2(pipes[1],2);

如果你想要分离输出,你可能需要使用非阻塞读取和 select() 或 poll()

另外:在调用 exec 之后,您应该打印一条错误消息,如果一切正常,则 exec 不会返回,但如果 exec 出现问题,很高兴知道。

std::cerr << "exec failed!";

我使用了这段代码并取得了成功:

#include <stdlib.h> 
#include <iostream> 
#include <sys/types.h> 
#include <sys/wait.h> 
#include <unistd.h> 
#include <fcntl.h>
int main(){
    char *const parmList[] = {"/usr/bin/strace", "ps", NULL};
    int pipes[2];
    pipe(pipes);
    pid_t child = fork();
    if(child == 0){
        close(pipes[0]);
        dup2(pipes[1],2);
        execv(parmList[0], parmList);
          std::cerr << "exec fail\n" ;
    }
    else{               
        int status;
        wait(&status);

        fcntl(pipes[0], F_SETFL, O_NONBLOCK | O_ASYNC); 
        char buf[128] = {0}; 
        ssize_t bytesRead; 
        std::string stdOutBuf; 
        while(1) {
            bytesRead = read(pipes[0], buf, sizeof(buf)-1);
            if (bytesRead <= 0)
                break;
            buf[bytesRead] = 0;
            stdOutBuf += buf;
        } 
        std::cout << "<stdout>\n" << stdOutBuf << "\n</stdout>" << std::endl; 
    }
    close(pipes[0]);
    close(pipes[1]);

    return 0;
}

高温高压

于 2014-12-23T07:01:07.150 回答