Профилировать процесс через его потомка и потом убить потомка - PullRequest
0 голосов
/ 08 июня 2018

Я пытаюсь найти способ профилировать в C процесс через своего потомка, и через мгновение родительский процесс убивает своего потомка, чтобы прекратить профилирование.Я использую 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 .Это пример кода, который может запускать родительский процесс:

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

Я не получаю вывод от perf при запуске этого кода.Мне нужно убить родительский процесс, чтобы получить вывод.

Если я помещу спящий вызов перед тем, как убить дочерний процесс, то программа выведет пустой файл.

EDIT:

stat аргумент является примером в моей команде, я также хочу использовать record аргумент
Как уже упоминалось Зуланом, если я использую SIGINT вместо SIGKILL, я получу вывод, но я могу получить его, только если основной процесс спит в течение 1 секунды.

Ответы [ 2 ]

0 голосов
/ 08 июня 2018

Вы должны отправить SIGINT вместо SIGKILL, чтобы позволить perf корректно завершить работу и создать действительный выходной файл.Синхронизация между дочерним процессом perf и основным процессом будет по-прежнему несовершенной, поэтому, если основной процесс не занимает много времени, как в вашем примере, вполне возможно, что никакой выходной файл не будет создан вообще.Это также влияет на точность собранных данных.С настройкой использования perf в качестве дочернего процесса, а не наоборот, вы не сможете реально улучшить его.

0 голосов
/ 08 июня 2018

проблема в том, что perf присоединяется к процессу, а затем ожидает завершения процесса для счетчиков печати.попробуйте добавить, например, параметр

-I msec 

к perf как -I 1000, чтобы печатать счетчики каждые 1 с.изменив ваши аргументы на execvp на

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

, а ваш inc на цикл, похожий на

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

, в то время как приводим к результатам, хотя файл не закрывается должным образом () в этом подходе.Я хотел бы создать небольшой двоичный файл, который исполняет perf с таймаутом, изящно закрывает файл и запускает его от дочернего элемента.

...