Search code examples
cforkprofilingperfexecvp

Profile a process via its child and kill the child afterwards


I am trying to figure out a way to profile in C a process via its child and after a moment the parent process kills its child to stop profiling. I am using perf to profile my application. perf is going to output its result in a file when killed. It looks like this in a bash script :

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

What I have done so far :

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

I have an issue getting the output of perf. This is an example of code that could run the parent process :

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

I am not getting any output from perf when running this code. I have to kill the parent process to get an output.

If I put a sleep call before killing the child process, then the program will output an empty file.

EDIT :

stat argument is an example in my command, I want also to use the record argument
As mentioned by Zulan, if I use SIGINT instead of SIGKILL, I will get an output, but I can get one only if the main process sleeps for 1 second.


Solution

  • You should send a SIGINT instead of a SIGKILL in order to allow perf to shutdown cleanly and produce a valid output file. The synchronization between the perf child process and the main process will still be imperfect - so if the main process doesn't take significant time as in your example, it is easily possible that no output file is generated at all. This also affects the accuracy of collected data. With the setup of using perf as a child process rather than vice-versa, you cannot really improve it.