通过其孩子描述一个过程,然后杀死孩子

时间:2018-06-08 08:47:17

标签: c fork profiling perf execvp

我试图找出一种通过其子进程在 C 进程中进行分析的方法,过了一会儿,父进程会终止其子进程以停止分析。我正在使用性能来分析我的应用程序。 perf将在杀死时将其结果输出到文件中。在bash脚本中看起来像这样:

./run &
perf stat -o perf.data -p <pid_run> &
kill -9 <pid_perf>

到目前为止我做了什么:

 #include <stdio.h>
 #include <stdlib.h>
 #include <signal.h>
 #include <sys/types.h>
 #include <unistd.h>
 #include <fcntl.h>

 static pid_t perf_id;

 void start() {
   char *filename="test_data";
   char ppid_str[24];

   pid_t pid = fork();
   if (pid == 0){

      pid_t ppid = getppid();
      sprintf(ppid_str, "%d",ppid);
      char *args[] = {"/usr/bin/perf", "stat","-p",ppid_str,"-o", filename, NULL};
      execvp(args[0], args);
   }
   else {

      perf_id = pid
   }
}

void stop() {
  kill(perf_id,SIGKILL);
}

我在获取性能的输出时遇到问题。 这是可以运行父进程的代码示例:

int main() {
    start();
    int a = 0;
    a+=1;
    stop();
    // ... // There are other instructions after the stop
    return 0;
 }

运行此代码时,我没有从perf获得任何输出。我必须杀死父进程才能获得输出。

如果我在杀死子进程之前进行了一次sleep调用,那么程序将输出一个空文件。

编辑:

stat 参数是我命令中的一个示例,我还想使用记录参数
正如Zulan所提到的,如果我使用SIGINT而不是SIGKILL,我将得到一个输出,但只有当主进程休眠1秒时我才能获得一个输出。

2 个答案:

答案 0 :(得分:1)

您应该发送SIGINT而不是SIGKILL,以便允许perf干净地关闭并生成有效的输出文件。 perf子进程和主进程之间的同步仍然不完善 - 因此如果主进程没有像您的示例那样花费大量时间,则很可能根本不会生成任何输出文件。这也会影响收集数据的准确性。设置使用perf作为子进程而不是反之亦然,您无法真正改进它。

答案 1 :(得分:0)

问题是perf将自身附加到进程,然后等待进程终止以打印计数器。尝试添加例如

-I msec 

选项,像-I 1000一样每隔1秒打印一次计数器。 将你的args更改为execvp

char *args[] = {"/usr/bin/perf", "stat", "-p",ppid_str,"-o", filename, "-I", "1000", NULL};

并将你的公司转为类似

的循环
while (a < 10) {
    a += 1;
    sleep(1);
}

虽然在这种方法中文件没有正确关闭(),但是会产生结果。 我会创建一个小的二进制文件,执行perf超时并正常关闭文件并从子进程运行。