在我的下面的代码中,如果我将old_act
声明为全局变量,那么程序运行正常。如果在main中声明:
有人可以帮助我理解发生的事情。
void sighandler(int signum)
{
printf("Caught signal:%d pressed ctrl+c!!\n",signum);
}
int main()
{
struct sigaction act_h;
struct sigaction old_act;
act_h.sa_handler = sighandler;
// act_h.sa_flags = SA_RESTART;
sigaction(SIGINT,&act_h,&old_act);
printf("This is an infinite loop\n");
int remain=sleep(10);
printf("remaining time in sec : %d\n",remain);
printf("Before second sleep\n");
sleep(10);
printf("This is an infinite loop\n");
return 0;
}
从gdb看起来,某些函数调用发生在非法位置,但不确定:
This GDB was configured as "i686-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/diwakar/Documents/my_C_codes/L2IT/SigHandling/a.out...done.
[New LWP 5661]
warning: Can't read pathname for load map: Input/output error.
Core was generated by `./a.out'.
Program terminated with signal 11, Segmentation fault.
#0 0xb77c1938 in ?? ()
(gdb)
(gdb) bt
#0 0xb77c1938 in ?? ()
Cannot access memory at address 0xe
(gdb) run
Starting program: /home/diwakar/Documents/my_C_codes/L2IT/SigHandling/a.out
This is an infinite loop
^C
Program received signal SIGINT, Interrupt.
0xb7fdd424 in __kernel_vsyscall ()
(gdb) bt
#0 0xb7fdd424 in __kernel_vsyscall ()
#1 0xb7ed2f00 in nanosleep () from /lib/i386-linux-gnu/libc.so.6
#2 0xb7ed2d1f in sleep () from /lib/i386-linux-gnu/libc.so.6
#3 0x08048502 in main () at signal.c:33
(gdb) disassemble
Dump of assembler code for function __kernel_vsyscall:
0xb7fdd414 <+0>: push %ecx
0xb7fdd415 <+1>: push %edx
0xb7fdd416 <+2>: push %ebp
0xb7fdd417 <+3>: mov %esp,%ebp
0xb7fdd419 <+5>: sysenter
0xb7fdd41b <+7>: nop
0xb7fdd41c <+8>: nop
0xb7fdd41d <+9>: nop
0xb7fdd41e <+10>: nop
0xb7fdd41f <+11>: nop
0xb7fdd420 <+12>: nop
0xb7fdd421 <+13>: nop
0xb7fdd422 <+14>: int $0x80
=> 0xb7fdd424 <+16>: pop %ebp
0xb7fdd425 <+17>: pop %edx
0xb7fdd426 <+18>: pop %ecx
0xb7fdd427 <+19>: ret
End of assembler dump.
(gdb)
答案 0 :(得分:6)
尝试在分配之前将act_h
的所有成员重置为零。很可能sa_flags
具有一些随机值,这使得信号操作表现得不同。
int main()
{
struct sigaction act_h;
struct sigaction old_act;
//reset all members
memset(&act_h, 0, sizeof(act_h));
act_h.sa_handler = sighandler;
.... //continue your code;
}
答案 1 :(得分:1)
您必须使用一个sigemptyset()
或sigfillset()
来初始化信号集。或者,在您的具体情况中:
sigemptyset(&act_h.sa_mask);
在你的情况下,请记住C没有像“默认构造函数”之类的东西。因此,信号集和其他自动变量不会自动初始化,很可能包含垃圾值。
另外,请注意,直接将所讨论的结构设置为零是正确初始化空信号集的不可靠方法。