2011-07-15 50 views
3

我試圖執行檢查點函數來檢查點進程。我通過分派子進程來做到這一點。不過,我需要在開始時暫停子進程。稍後,我們可以通過取消暫停子進程並使其自行終止來從檢查點重新啓動。在開始時停止子進程

以下是我爲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函數調用中停止。

+0

現在我找到了部分的權利,通過發行募集(SIGTRAP),剛剛經過的ptrace(PTRACE_TRACEME,0,0,0)。現在我只需要父進程在調用restart_from_checkpoint時退出。 – MetallicPriest

+0

您是用C還是C++編譯?我只在這裏看到C代碼。 – Puppy

+0

如果我使用C或C++,這無關緊要嗎? – MetallicPriest

回答

0

好的,我找到了解決方案。它的工作現在完美。這裏是你感興趣的人的代碼。

#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

您可以使用IPC信號或信號USR1 ...

+0

如何?我試圖使用SIGUSR1和信號,但沒有運氣!你能詳細說明一下還是展示一些代碼示例。 – MetallicPriest

+0

ptrace中是否有任何參數可用於在開始時停止分叉進程,並稍後以PTRACE_CONT開始。我正在考慮這一方面。如果有的話,我不需要混淆信號! – MetallicPriest

+0

通過在ptrace(PTRACE_TRACEME,0,0,0)之後調用raise(SIGTRAP)來解決第一部分。 – MetallicPriest