背景
struct sigaction用于为处理中断的小型C程序设置处理程序。当我收到" Segmentation fault(core dumped)"完成第二个处理程序的实现后的错误消息。我以完全相同的方式设置两个处理程序。第一个中断处理程序工作正常而没有初始化sigaction结构,但是,当我完成第二个处理程序的实现时,我收到了seg错误。
问题:
为什么用memset()初始化sigaction结构有助于修复错误?
CODE:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <signal.h>
#include <string.h>
#define ALARMSECONDS 3
int numSigints = 5;
/* Handler function that prints out the current time on a SIGALRM interrupt. */
static void hdl(int signum)
{
time_t currTime;
time(&currTime);
printf("\ncurrent time is %s", ctime(&currTime));
alarm(ALARMSECONDS);//re-arm the alarm
}
/* Handler function that captures SIGINT interrupts 5 times before
actually exiting. Makes use of global variable to keep track of
number of times the interrupt was sent.
*/
static void sigint_hdl(int signum)
{
numSigints -= 1;
if(numSigints == 0)
{
printf("\nFinal Control-c caught. Exiting.\n");
exit(1);
}
else
{
printf("\nControl-c caught. %d more before program is ended.\n",
numSigints);
}
}
/* Periodically prints out the current time in Unix date format using
sigaction interrupt handling.
*/
int main(int argc, char *argv[])
{
//
// vars
//
struct sigaction act;
struct sigaction sigint_act;
memset(&act, '\0', sizeof(act));//TODO Why does this fix SEGFAULT???
//
// intro
//
printf("Date will be printed every 3 seconds.\n");
printf("Enter ^C 5 times to end the program.\n");
//
// set alarm to go off in 3 seconds
//
alarm(ALARMSECONDS);
//
// set handler of the sigaction to 'hdl' function defined above
//
act.sa_handler = hdl;
sigint_act.sa_handler = sigint_hdl;
//
// activate sigaction
//
if(sigaction(SIGALRM, &act, NULL) < 0)
{
perror("sigaction -- SIGALRM");
return 1;
}
if(sigaction(SIGINT, &sigint_act, NULL) < 0)
{
perror("sigaction -- SIGINT");
return 1;
}
//
// infinite loop
//
while(1) {
}
return 0;
}
答案 0 :(得分:3)
sigaction
结构中有许多字段。将它们全部设为零会将它们设置为默认值。
如果它们不是零,它们将以系统调用文档中描述的任何方式进行解释。一个示例是两个字段sa_mask
和sa_sigaction
。并且根据sa_mask
的值,将调用sa_sigaction
处理程序而不是您的代码安装的预期信号处理程序。并且由于你没有初始化指针,它将有一些垃圾值,并且将尝试不仅仅取消引用,而是通过垃圾指针调用函数。
因此,如果您未能初始化结构,则会得到未定义的行为。有时它会起作用,有时它不会以神秘的方式发生,例如崩溃。
通过将整个结构清除为零,您可以确保将发生默认行为,并通过它们对结构所做的任何非默认设置进行修改。
获得的经验教训:始终清除并初始化传递给库函数的所有结构。