在我下面的代码中,如果我将old_act
声明为全局variables,那么程序工作正常。 如果在主内部声明:
有人可以帮助我理解发生了什么。
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)
尝试将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; }
您必须使用一个sigemptyset()
或sigfillset()
来初始化一个信号集。 或者,在你的具体情况下:
sigemptyset(&act_h.sa_mask);
在你的情况下,记住,C没有像“默认构造函数”或东西的东西。 所以,信号集和其他自动变量没有被自动初始化,并且很可能包含垃圾值。
此外,请注意,直接memsetting以零结构的问题是不正确的方式正确初始化一个空的信号集。