2009-05-25 3 views
2

나는 waitpid() 및 signal()을 가지고 놀고 있으며 WIFSIGNALED (상태) = WIFSTOPPED (상태) = WIFCONTINUED (상태)를 반환하기위한 신뢰할 수있는 테스트 케이스를 찾고 있습니다. = 사실이지만 아무 것도 찾을 수 없습니다 ...WIFSIGNALED, WIFSTOPPED, WIFCONTINUED에 대한 C의 테스트 케이스

내 코드를 디버그 할 수 있도록 어떻게 그 사실을 반환 할 수 있는지 알려주시겠습니까? 당신의 검사 결과에 또한

, 나는 그 매크로가 도움이 될 것입니다 테스트하는 신호()를 잡을해야하는지 신호에 대한 몇 가지 힌트 ...

답변

3
#include <errno.h> 
#include <signal.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <sys/wait.h> 
#include <unistd.h> 

#define NELEMS(x) (sizeof (x)/sizeof (x)[0]) 

static void testsignaled(void) { 
    kill(getpid(), SIGINT); 
} 

static void teststopped(void) { 
    kill(getpid(), SIGSTOP); 
} 

static void testcontinued(void) { 
    kill(getpid(), SIGSTOP); 
    /* Busy-work to keep us from exiting before the parent waits. 
    * This is a race. 
    */ 
    alarm(1); 
    while(1) {} 
} 

int main(void) { 
    void (*test[])(void) = {testsignaled, teststopped, testcontinued}; 
    pid_t pid[NELEMS(test)]; 
    int i, status; 
    for(i = 0; i < sizeof test/sizeof test[0]; ++i) { 
     pid[i] = fork(); 
     if(0 == pid[i]) { 
     test[i](); 
     return 0; 
     } 
    } 
    /* Pause to let the child processes to do their thing. 
    * This is a race. 
    */ 
    sleep(1); 
    /* Observe the stoppage of the third process and continue it. */ 
    wait4(pid[2], &status, WUNTRACED, 0); 
    kill(pid[2], SIGCONT); 
    /* Wait for the child processes. */ 
    for(i = 0; i < NELEMS(test); ++i) { 
     wait4(pid[i], &status, WCONTINUED | WUNTRACED, 0); 
     printf("%d%s%s%s\n", i, WIFCONTINUED(status) ? " CONTINUED" : "", WIFSIGNALED(status) ? " SIGNALED" : "", WIFSTOPPED(status) ? " STOPPED" : ""); 
    } 
    return 0; 
} 
-1

당신은()를 포크와 자식 프로세스에 특정 신호를 보낼 수 있습니까? 이 시나리오에서 하위 프로세스는 테스트 케이스입니까?

편집

내 대답은 C 테스트를 코딩에 관한 것입니다. 당신은 포크, 당신의 자식 프로세스의 PID (신호 처리기가 설치된 프로세스)를 얻은 다음 kill(2)을 사용하여 신호를 보낼 수 있습니다. 이렇게하면 종료 상태를 테스트 할 수 있습니다.

+0

물론 나는 이미 특정 신호를 찾고 있는데, 어떤 신호가 어떤 매크로를 true로 만들지는 알고 있습니다 ...bash를 통해 특정 프로세스로 어떻게 전송하여 테스트 할 수 있습니까? 내가 알고 싶은 것입니다. –

+0

kill (1), man 1 kill을 사용하여 자세한 정보 확인 – dfa

1

아래와 같은 프레임 워크를 사용하면 wait()waitpid() 호출 결과를 확인할 수 있습니다.

pid_t pid = fork(); 

if (pid == 0) { 
    /* child */ 
    sleep(200); 
} 
else { 
    /* parent */ 
    kill(pid, SIGSTOP); 

    /* do wait(), waitpid() stuff */ 
} 

당신은 실제로 전송됩니다 (signal() 또는 관련 기능을 사용) 신호를 잡을 필요가 없습니다. signal()은 특정 신호에 대한 기본 동작을 무시하는 처리기를 설치합니다. 따라서 프로세스를 종료하는 신호를 확인하려면 해당 기본 동작이있는 신호를 선택하십시오. - "man -s7 signal"은 신호의 기본 동작을 자세히 알려줍니다. 당신이 WIFSTOPPED(status)을 위해 사용 SIGSTOP 언급 한 매크로, WIFSIGNALED(status)

에 대한 WIFCONTINUED (status)에 대한 SIGCONTSIGINT 당신이, 당신이 살인을 사용할 수있는 프로세스에 신호를 보내 ("man kill"참조) 테스트를 위해 더 많은 유연성을 원하는 경우에 대한

. kill -l은 보낼 수있는 모든 신호를 나열합니다.

+0

위에서 설명한 것과 동일하지만 가장 필요한 것은 해당 매크로를 테스트하는 특정 신호입니다. 그래도 문제가 있습니다. SIGSTOP을 처리 할 수 ​​없다면 WIFSTOPPED를 어떻게 확인할 수 있습니까? –

+0

@Ricardo, 당신은 자식에서'SIGSTOP'을 처리 할 수 ​​없습니다; 'WIFSTOPPED'는 부모에서 사용하기위한 것입니다 :'if (pid! = 0 && WIFSTOPPED (status) {/ * do something * /}' –

1

WIFSIGNALED 취급은 쉽습니다. 자식 프로세스는 kill() 시스템 호출로 자살 할 수 있습니다. 코어 덤프를 확인할 수도 있습니다 - 일부 신호는이를 생성합니다 (SIGQUIT, IIRC). 일부 신호는 (SIGINT)하지 않습니다.

WIFSTOPPED 처리가 더 어려울 수 있습니다. 시도해 볼 간단한 단계는 자식이 kill() 시스템 호출을 사용하여 SIGSTOP을 다시 전송하는 것입니다. 사실, 그게 효과가 있다고 생각합니다. SIGTTIN, SIGTTOU 및 SIGTSTOP을 확인하고 싶을 수도 있습니다 - 저는 그들이 WIFSTOPPED라고 생각합니다. (SIGSTOP은 디버거가 non-POSIX 시스템 콜을 통해 실행하는 프로세스 인 ptrace()에서만 실행될 수 있습니다.)

WIFCONTINUED는 부모님이해야한다고 생각합니다. 프로세스가 중지 된 것을 감지하면 호출 코드는 SIGCONT 신호 (kill())를 보내 계속 진행해야합니다. 아이는 이것을 스스로 제공 할 수 없다. 그것은 멈췄다. 다시 말하면 걱정할 여분의 주름이 있는지 확실하지 않습니다. 아마도.

관련 문제