0

I don't know why this program crashs when the alarm handler finishs its work, due to malloc statement (LINE1) although it is never been called

When I comment LINE1 OR LINE2 the code continues without any problems, but when commenting LINE3 the program still crashs

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>

void handler (int sig) {
    printf ("Hi I'm at handler\n");
}

int main() {
    int *pm, f = 0;

    struct sigaction sa; 

    sa.sa_handler = &handler;

    sigaction (SIGALRM, &sa, NULL);

    alarm (2);        // LINE1

    while (1) {
            if (f == 1)     {   
                    pm = (int *) malloc (sizeof (int));     // LINE2
                    if (pm)
                            printf ("memory allocated at loop\n");
            }   
            else {
                    printf ("Wait\n");
                    usleep (200000);                      // LINE3
            }   
    }   

return 0;
}

Result:

Wait
Wait
Wait
Wait
Wait
Wait
Wait
Wait
Wait
Wait
Hi I'm at handler
Segmentation fault (core dumped)

Notes:

This problem faces me in a larger application that can't be posted here so I wrote this program to show it I'm working under Ubuntu and compiling with gcc

  • using printf (and any 'sleeping' function) within signal handlers isn't a good idea – Shmil The Cat Apr 19 '14 at 17:34
  • 1
    Read [How to avoid using printf in a signal handler?](http://stackoverflow.com/questions/16891019/how-to-avoid-using-printf-in-a-signal-handler) that also answers why to avoid.. – Grijesh Chauhan Apr 19 '14 at 17:37

1 Answers1

2

There is nearly nothing you may do in a signal handler, nearly everything causes Undefined Behavior.
The only thing the C standard guarantees is setting of a volatile sig_atomic_t.
The POSIX standard allows quite a lot of other functions, but not printf.

In particular, the printf()-call might interrupt other access to the same output stream and other memory allocacion requests, causing unrestrained havoc.

As "nos" commented, using a mostly uninitialised structure for calling sigaction was also not the wisest decision.

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
  • 2
    Also the struct sigaction sa; isn't properly initialized, there many more members than sa_handler. better memset(&sa, 0, sizeof sa); – nos Apr 19 '14 at 17:35
  • 1
    @MohamedYacoutAbouSamra: Please say you also read the other part. Heisenbugs are so much fun. – Deduplicator Apr 19 '14 at 17:47
  • Yes, Noted this valuable note, the printf statement inside the handler was just for testing – Mohamed Yacout Apr 19 '14 at 17:52
  • @Deduplicator Ont only volatile but also `sig_atomic_t` the problem is signal handler can be called asynchronously (it is not called like normal function) that flag operation should be atomic.--- additionally, you should your program leak memory because melloc function function over writes. thought OP should recompile program and run again, add [this link](http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_21.html#SEC352). – Grijesh Chauhan Apr 19 '14 at 18:07
  • The down vote (not mine) might be because POSIX permits quite a few functions to be called in a signal handler: http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_04_03_03 (though `printf()` isn't one of them). – Michael Burr Apr 19 '14 at 18:48