2011-05-09 14 views
3

나는이 프로그램을 가지고 있는데 왜 세분화 오류가 발생했는지에 대한 아이디어가 있습니까? 여기 세분화 오류가 발생하는 이유는 무엇입니까?

#include <stdlib.h> 
#include <ctime> 
#include <stdio.h> 
#include <signal.h> 
#include <errno.h> 
#include <string.h> 
#include <unistd.h> 
#include <iostream> 
#include <dlfcn.h> 

#define LT_SIGACTION (*lt_sigaction) // For handle to actual sigaction in libc 

static int (*lt_sigaction)(int, const struct sigaction*, struct sigaction*); // For sigaction wrapper 
static void sig_handlerTimer1(int,siginfo_t*,void*); 
timer_t timerid; 

int main() 
{ 
    int i; 
    static struct sigaction sa; 

    static struct sigevent sevp; // argument to timer_create 
    static struct itimerspec its; // argument to timer_gettime 

    if(!lt_sigaction) { 
     lt_sigaction = (int(*)(int, const struct sigaction*, struct sigaction*)) dlsym(RTLD_NEXT, "sigaction"); 
     if (!lt_sigaction) { 
      fprintf(stderr, "Could not resolve 'sigaction' in 'libc.so': %s\n", dlerror()); 
      exit(1); 
     } 
    } 

    memset (&sevp, 0, sizeof (struct sigevent)); 
    sevp.sigev_value.sival_ptr = &timerid; 
    sevp.sigev_notify = SIGEV_SIGNAL; 
    sevp.sigev_notify_attributes = NULL; 
    sevp.sigev_signo = SIGUSR1; 

    /* Setting timer interval */ 
    its.it_interval.tv_sec = 0; 
    its.it_interval.tv_nsec = 0; 

    /* Setting timer expiration */ 
    its.it_value.tv_sec = 2; // First expiry after 1 sec 
    its.it_value.tv_nsec = 0; 

    /* Setting the signal handlers before invoking timer*/ 
    sa.sa_sigaction = sig_handlerTimer1; 
    sa.sa_flags = 0; 
    LT_SIGACTION(SIGUSR1, &sa, NULL); 
    // Even sigaction(SIGUSR1, &sa, NULL); gives SEGV 
    if (timer_create(CLOCK_REALTIME, &sevp, &timerid) == -1) 
    { 
     fprintf(stderr, "LeakTracer (timer_trackStartTime): timer_create failed to create timer. " \ 
       "Leak measurement will be for entire duration of the execution period:%s \n", strerror(errno)); 
     return 0; 

    } 

    if (timer_settime(timerid, 0, &its, NULL) == -1) 
    { 
     fprintf(stderr, "LeakTracer (timer_trackStartTime): timer_settime failed to set the timer. " \ 
       "Leak measurement will be for entire duration of execution period:%s \n", strerror(errno)); 
     return 0; 

    } 

    for(i=0; i<10; i++) 
    { 
     printf("%d\n",i); 
     sleep(1); 
    } 
} 

void sig_handlerTimer1(int signum,siginfo_t* sf, void* au) 
{ 
    if(sf==NULL) 
    { 
     printf("sf is NULL\n"); 
     exit(1); 
    } 
    if((sf->si_value.sival_ptr)!=&timerid) //SEGV received here 
    { 
     printf("Stray signal\n"); 
    } 
    else { 
     int flag = 1; 
     printf("Caught signal: %d\n",signum); 
     if (timer_delete(timerid) < 0) 
     { 
      fprintf(stderr, "timer deletion failed. " \ 
        "This may result in some memory leaks (sig_handlerTimer1):%s \n", strerror(errno)); 
     } 
    } 
} 

은 GDB 역 추적입니다 :

enter code here 
Program received signal SIGUSR1, User defined signal 1. 
0x00e52402 in __kernel_vsyscall() 

(gdb) s 

Single stepping until exit from function __kernel_vsyscall, 

which has no line number information. 
sig_handlerTimer1 (signum=10, sf=0x33, au=0x0) at signalTimer.cc:73 
73  void sig_handlerTimer1(int signum,siginfo_t* sf, void* au) 

(gdb) s 


Breakpoint 1, sig_handlerTimer1 (signum=10, sf=0x33, au=0x0) at signalTimer.cc:75 
75    if(sf==NULL) 
(gdb) s 

80    if((sf->si_value.sival_ptr)!=&timerid) 

(gdb) s 

Program received signal SIGSEGV, Segmentation fault. 

0x08048a9f in sig_handlerTimer1 (signum=10, sf=0x33, au=0x0) at signalTimer.cc:80 

80    if((sf->si_value.sival_ptr)!=&timerid) 

(gdb) bt 
#0 0x08048a9f in sig_handlerTimer1 (signum=10, sf=0x33, au=0x0) at signalTimer.cc:80 
#1 <signal handler called> 
#2 0x00e52402 in __kernel_vsyscall() 
#3 0x00724970 in __nanosleep_nocancel() from /lib/libc.so.6 
#4 0x007247bf in sleep() from /lib/libc.so.6 
#5 0x08048a5a in main() at signalTimer.cc:69 

(gdb) q 
The program is running. Exit anyway? (y or n) y 

이는 C++ 코드이며, g를 사용하여 컴파일 ++ 비록 sigaction 사람 페이지에서 C

답변

6

에서 거의 차이, 당신 플래그가 정의되어 있어야합니다.

sa.sa_flags = SA_SIGINFO; 

그렇지 않으면 3 개의 인수로 함수를 호출하지 않습니다. lt_sigaction에 사용법에 차이가 있는지 확실하지 않습니다.

+0

@ B.Mitch : 고맙습니다. 시험해 봅시다. – kingsmasher1

+0

@ B.Mitch : 와우 ​​!!! 고마워요, 고마워요 .. 오랜 시간 동안 이걸 시도해 봤는데 ... 사람들이 더 자세히 man 페이지를 읽어야한다고 ... 고맙습니다. – kingsmasher1

+0

이것은 나와 모든 프로그래머에게 교훈이며, 맨 페이지를주의 깊게 읽는 것이 중요하다는 것을 보여줍니다. 우리는 무엇이든 놓칠 수 없습니다. – kingsmasher1

관련 문제