我有这个程序,知道它为什么会出现分段错误吗?
#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的差别很小
答案 0 :(得分:6)
在sigaction
手册页中,您应该定义SA_SIGINFO
标志:
sa.sa_flags = SA_SIGINFO;
否则,它不是用3个args调用你的函数。不确定lt_sigaction
在使用方面是否有任何差异。