3

In my below code, if I'm declaring old_act as a global variable then the program works fine. If declared inside main:

  1. If SA_RESTART used, it works fine
  2. If SA_RESTART not used, it causes segmentation fault.

Can someone please help me comprehend what is happening.

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

From gdb it looks like some function call is happening at illegal location ,but not sure:

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) 
Grijesh Chauhan
  • 57,103
  • 20
  • 141
  • 208
Diwakar Sharma
  • 415
  • 1
  • 9
  • 26

2 Answers2

7

Try resetting all members of act_h to zero before assigning it. Most likely the sa_flags has some random value which is making the signal action to behave differently.

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;

}
Rohan
  • 52,392
  • 12
  • 90
  • 87
  • That worked , thanks..!! Can you explain what was happening due to not memsetting act_h and why was it affected by declaration of old_act? something like saving the old action into old_act but act_h has some garbage (like in sa_flags you said) ,or problem is caused while retrieving from old_act...? – Diwakar Sharma Sep 05 '13 at 03:13
  • Also , why was it working with SA_RESTART set... too many questions :) – Diwakar Sharma Sep 05 '13 at 04:01
  • @DiwakarSharma, `memset()` set all bits to 0, i.e. setting all members of structure to 0. Otherwise, it may have some garbage data, which the `sigaction()` or signal dispatcher interpreted differently causing the error. – Rohan Sep 05 '13 at 04:04
1

You must use one sigemptyset() or sigfillset() to initialize a signal set. Or, in Your specific case:

sigemptyset(&act_h.sa_mask);

In Your case, bare in mind that C does not have stuff like "default constructor" or something. So, the signal set and other automatic variables are not being initialized automagically and most likely contains garbage values.

Also, be aware that bluntly memsetting to zeroes the structure in question is unreliable way of properly initializing an empty signal set.

Kamiccolo
  • 7,758
  • 3
  • 34
  • 47