2011-05-09 7 views
3

J'ai ce programme, aucune idée de pourquoi il obtient la faute de segmentation?Pourquoi la faute de segmentation?

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

Voici le GDB backtrace:

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'est un code C++ et compilé en utilisant g ++, bien que très peu de différence de C

Répondre

6

De la page de manuel sigaction, vous devrait avoir le drapeau SA_SIGINFO défini:

sa.sa_flags = SA_SIGINFO; 

Sinon, il n'appelle pas votre fonction avec 3 arguments. Vous ne savez pas si lt_sigaction présente des différences d'utilisation.

+0

@ B.Mitch: Merci, laissez-moi essayer. – kingsmasher1

+0

@ B.Mitch: Wow !!! Merci beaucoup, beaucoup de remerciements ... J'essayais cela depuis très longtemps ... il est dit que les gens devraient lire plus attentivement les pages de manuel ... merci et que Dieu vous bénisse. – kingsmasher1

+0

Ceci est une leçon pour moi et tous les programmeurs, cela montre l'importance de lire attentivement les pages de manuel. Nous ne pouvons rien manquer, pas même un mot. – kingsmasher1

Questions connexes