2014-12-23 2 views
1

Я хочу проанализировать вывод strace в моей программе на C++. При запуске /bin/strace ps из моего приложения я получаю вывод из ps, но не из strace, а выход strace печатается в stdout (мой терминал). Я использую стандартную методику использования труб и перенаправления потоков.Как захватить вывод strace в C++-программе

Вот мой источник:

#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; 
} 

Как я могу получить выход Трассирования в моей программе?

ответ

1

Трассирования пишет stderr не stdout, если вы хотите, чтобы захватить выход Трассирования просто использовать STDERR вместо стандартного вывода

Изменение dup2 линия как этого

 dup2(pipes[1],2); 

Если вы хотите комбинированного Трассирование и п.п. этого сделать:

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

Если вы хотите раздельный выход, вам, вероятно, понадобится нам e неблокирует чтение и 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; 
} 

HTH

+0

Спасибо за ваш ответ, но если перенаправить стандартный поток ошибок, то он висит полностью, даже в том случае, когда все родитель делать ждёт (& статус) –

+0

hmm, он должен работать. Я не могу заставить ваш источник компилироваться. – Jasen

+0

странно, я скомпилирую его с g ++ 4.9.1, он дает некоторые предупреждения из-за устаревшего преобразования, но компилирует –

Смежные вопросы