2012-03-27 2 views
0

SIGSEGV가 보내질 때 호출 할 시그널 핸들러를 만들었습니다. C를 사용하여 프로그램을 작성하고 Linux 및 Intel x86 프로세서를 사용하고 있습니다. sig 핸들러에서는 siginfo_t 구조체를 통해 전달되는 si_addr에 문제를 일으키는 명령어 주소 대신 값 0이 주어진 것처럼 보입니다. 나는 sigaction에 SIG_INFO 플래그를 설정하여 idk가 왜 이런 일이 일어나고 있는지를 보여줍니다.SIGSEGV의 시그널 처리 문제들

int main(){ 
    mprotect(..., PROC_READ | PROC_WRITE /* | PROC_EXEC */); //cannot execute page 

    someMethodOnRestrictedPage(); 
    //do some stuff 
} 

void init_sighandler(void) { 

    //initialize the sigaction so that sig handler is called when a SIGSEGV is thrown 
    struct sigaction * action; 

    action = (struct sigaction *) malloc(sizeof(struct sigaction)); 

    action->sa_sigaction = sighandler; 
    sigemptyset (&action->sa_mask); 

    action->sa_flags = 0; 

    sigaddset(&action->sa_mask, SA_SIGINFO); 
    sigaddset(&action->sa_mask, SA_RESTART); 

    sigaction(SIGSEGV, action, NULL); 
} 

void sighandler(int sig, siginfo_t *siginfo, void *ucp){ 
    printf("%x\n", siginfo->si_addr); // prints out 0 
} 
+0

내가 궁금한데, 왜 세분화 오류를 처리하려고합니까? 핸들러에서 무엇을 할 계획입니까? –

+0

의도적으로 SIGSEGV를 생성하기 위해 특정 메모리 페이지에 대한 액세스를 제한하고 있습니다. – user972276

+1

당신이 어떤 플랫폼을 사용하고 있는지 알면 도움이 될 것입니다. –

답변

1

귀하의 .sa_flags 취소했던 SA_SIGINFO 비트를 가지고 : 여기

몇 가지 예제 코드입니다. http://pubs.opengroup.org/onlinepubs/7908799/xsh/sigaction.html을 인용

,

SA_SIGINFO

지워지고 신호가 잡힌 경우, 신호 끄는 기능으로 입력됩니다 signo가 유일한 인수가

void func(int signo);

신호 포착 기능. 이 경우 신호 포착 기능을 설명하기 위해 sa_handler 구성원을 사용해야하며 응용 프로그램은 sa_sigaction 구성원을 수정하면 안됩니다. SA_SIGINFO가 설정되고, 신호가 잡히면

신호 끄는 기능으로 입력한다 : 두 개의 부가적인 인자 신호 포획 함수에 전달

void func(int signo, siginfo_t *info, void *context);

. 두 번째 인수는 신호가 생성 된 이유를 설명하는 siginfo_t 유형의 객체를 가리 킵니다. 세 번째 인수는 유형이 ucontext_t 인 객체에 대한 포인터로 형변환되어 신호가 전달 될 때 중단 된 수신 프로세스의 컨텍스트를 나타낼 수 있습니다. 이 경우 신호 포착 기능을 설명하기 위해 sa_sigaction 구성원을 사용해야하며 응용 프로그램은 sa_handler 구성원을 수정하면 안됩니다.

si_signo 구성원에는 시스템 생성 신호 번호가 들어 있습니다.

si_errno 구성원은 구현에 따른 추가 오류 정보를 포함 할 수 있습니다. 0이 아닌 경우에는 신호가 생성 된 조건을 식별하는 오류 번호가 포함됩니다.

si_code 멤버는 신호의 원인을 식별하는 코드를 포함합니다. si_code 값이 0보다 작거나 같으면 프로세스에 의해 신호가 생성되고 si_pidsi_uid은 각각 프로세스 ID와 보낸 사람의 실제 사용자 ID를 나타냅니다. <signal.h> 헤더 설명에는 siginfo_t 유형의 요소에 대한 신호 특정 내용에 대한 정보가 들어 있습니다. 비트가 설정되어있는 경우 비트가 .sa_sigaction 분명하고, 경우

--end 인용

그래서은 sigaction은 .sa_handler를 사용합니다.

따라서 작성되지 않은 인수를 읽고 있으므로 정의되지 않은 동작이 발생합니다.

.sa_flags = SA_SIGINFO | ...을 설정하여 문제를 해결하십시오.

+0

예, 감사합니다! 나는 필요한 모든 것이 sigaddset (& action-> sa_mask, SA_SIGINFO)이라고 생각했다; 그것을 설정하지만 나는 그렇지 않을 것입니다. – user972276

관련 문제