通过 child 分析一个进程,然后杀死 child

Profile a process via its child and kill the child afterwards

我正在尝试找出一种方法来通过 child 在 C 中分析一个进程,片刻之后 parent 进程终止了它的 child 停止分析。我正在使用 perf 来分析我的应用程序。 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);
}

我在获取 perf 的输出时遇到问题。 这是一个可以 运行 parent 过程的代码示例:

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

当 运行 执行此代码时,我没有从 perf 获得任何输出。我必须终止 parent 进程才能获得输出。

如果我在终止 child 进程之前调用 sleep,那么程序将输出一个空文件。

编辑:

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

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

-I msec 

perf 选项 -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 超时并优雅地关闭文件和 运行 来自 child.

的文件

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