开发者

Why is the segmentation fault?

I have this program, any idea as to why it gets segmentation fault?

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

Here is the 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_handlerTime开发者_高级运维r1 (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 

This is a C++ code, and compiled using g++, although very little difference from C


From the sigaction man page, you should have the SA_SIGINFO flag defined:

sa.sa_flags = SA_SIGINFO;

Otherwise, it's not calling your function with 3 args. Not sure if lt_sigaction has any differences in usage.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜