2011-05-09 266 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 ++编译,虽然由C

回答

6

相差无几从sigaction手册页,你应该有SA_SIGINFO标志定义:

sa.sa_flags = SA_SIGINFO; 

否则,它不会用3个参数调用你的函数。不确定lt_sigaction在使用上有什么不同。

+0

@ B.Mitch:谢谢,让我试试。 – kingsmasher1 2011-05-09 13:33:51

+0

@ B.Mitch:哇!非常感谢你,谢谢..我很长时间以来一直在尝试......它说,人们应该更仔细地阅读手册页......谢谢你,上帝保佑你。 – kingsmasher1 2011-05-09 13:37:11

+0

这对我和所有程序员来说都是一个教训,它显示了仔细阅读手册页的重要性。我们不能错过任何事情,甚至一言不发。 – kingsmasher1 2011-05-09 13:39:13