Остановка дочернего процесса при запуске - PullRequest
3 голосов
/ 15 июля 2011

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

Вот код, который я написал для checkpoint и restart_from_checkpoint, а также пример их вызова.

#include <stdio.h>
#include <unistd.h>
#include <sys/ptrace.h>
#include <sys/wait.h>

pid_t checkpoint();
void restart_from_checkpoint( pid_t pid );

int main( int argc, char *argv[] )
{
  int i;
  pid_t child_pid;
  pid_t parent_pid = getpid();

  for( i = 0; i < 10; i++ )
  {
    if ( i == 4 )
    {
      printf( "%6s: Checkpointing!\n", (getpid() == parent_pid)? "parent":"child" );
      child_pid = checkpoint();
    }

    if ( i == 7 )
    {
      printf( "%6s: Restarting!\n", (getpid() == parent_pid)? "parent":"child" );
      restart_from_checkpoint( child_pid );
    }

    printf( "%6s: i = %d\n", (getpid() == parent_pid)? "parent":"child", i );
  }

  return 0;
}

pid_t checkpoint()
{
    pid_t pid;
    int wait_val;

    switch (pid=fork()) 
    {
    case -1: 
        perror("fork"); 
        break;
    case 0:         // child process starts
        ptrace(PTRACE_TRACEME,0,0,0);
        raise( SIGTRAP ); // Note that this is the solution to first part
                              // of the question, which I added after
                              // asking this question.
        break;  // child process ends
    default:        // parent process starts
        wait(&wait_val);
        return pid;
    }
}

void restart_from_checkpoint( pid_t pid )
{
    ptrace(PTRACE_CONT, pid, NULL, NULL);
    wait(NULL); // I'm just waiting here, but actually 
                //  I need to kill the calling process.
}

Я не знаю, как остановить дочерний процесс после вызова ptrace(PTRACE_TRACEME,0,0,0). Во-вторых, я не знаю, как убить родительский процесс, позволяя потомку продолжить на restart_from_checkpoint.

Лучше всего будет использовать параметр с ptrace, который останавливает разветвленный процесс в начале и позже запускается с PTRACE_CONT. К сожалению, PTRACE_TRACEME останавливается только при вызове функции exec.

Ответы [ 2 ]

0 голосов
/ 15 июля 2011

ОК, я нашел решение. Теперь работает отлично. Вот код для тех из вас, кто заинтересован.

#include <stdio.h>
#include <unistd.h>
#include <sys/ptrace.h>
#include <sys/wait.h>
#include <stdlib.h>

pid_t checkpoint();
void restart_from_checkpoint( pid_t pid );

int main( int argc, char *argv[] )
{
  int i;
  pid_t child_pid;
  pid_t parent_pid = getpid();

  for( i = 0; i < 10; i++ )
  {
    if ( i == 4 )
    {
      printf( "%6s: Checkpointing!\n", (getpid() == parent_pid)? "parent":"child" );
      child_pid = checkpoint();
    }

    if ( i == 7 && ( getpid() == parent_pid ) )
    {
      printf( "%6s: Restarting!\n", (getpid() == parent_pid)? "parent":"child" );
      restart_from_checkpoint( child_pid );
    }

    printf( "%6s: i = %d\n", (getpid() == parent_pid)? "parent":"child", i );
  }

  return 0;
}

pid_t checkpoint()
{
    pid_t pid;
    int wait_val;

    switch (pid=fork()) 
    {
    case -1: 
        perror("fork"); 
        break;
    case 0:         // child process starts
        ptrace(PTRACE_TRACEME,0,0,0);
        raise(SIGTRAP);
        break;  // child process ends
    default:        // parent process starts
        wait(&wait_val);
        return pid;
    }
}

void restart_from_checkpoint( pid_t pid )
{
    ptrace(PTRACE_CONT, pid, NULL, NULL);
    ptrace(PTRACE_DETACH, pid, NULL, NULL);
    exit( 1 );
}
0 голосов
/ 15 июля 2011

Вы можете использовать семафор IPC или СИГНАЛ USR1 ...

...