在启动时停止子进程

发布于 2024-11-24 07:01:49 字数 1950 浏览 1 评论 0原文

我正在尝试实现一个检查点函数来检查进程。我通过分叉子进程来做到这一点。但是我需要在开始时暂停子进程。稍后,我们可以通过取消暂停子进程并使父进程自行终止来从检查点重新启动。

以下是我为 checkpointrestart_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 函数调用处停止。

I'm trying to implement a checkpoint function to checkpoint a process. I do it by forking a child process. However I need to pause the child process at start. Later on, we can restart from a checkpoint by unpausing the child process and making the parent kill itself.

Here is the code I've written for checkpoint and restart_from_checkpoint along with an example of how to call them.

#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.
}

I don't know how to stop the child process after calling ptrace(PTRACE_TRACEME,0,0,0). Secondly, I don't know how to kill the parent process while letting the child continue at restart_from_checkpoint.

The best thing would be the possibility of using a parameter with ptrace that stops the forked process at the beginning and later started with PTRACE_CONT. Unfortunately, PTRACE_TRACEME only stops at an exec function call.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

扭转时空 2024-12-01 07:01:49

您可以使用 IPC 信号量或 SIGNAL USR1...

You can use a IPC semaphore or a SIGNAL USR1...

总以为 2024-12-01 07:01:49

好的,我找到了解决方案。它现在工作得很好。这是感兴趣的人的代码。

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

OK, I've found the solution. Its working perfectly now. Here is the code for those of you who are interested.

#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 );
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文