Zhe Chen
Zhe Chen

Reputation: 2957

Stops working when trying to `longjmp` from a signal handler

Here's my code:

#include <stdio.h>
#include <setjmp.h>
#include <signal.h>

jmp_buf buf;

void handler(int s);

int main(int argc, char **argv) {
    signal(SIGINT, handler);
    if (setjmp(buf)) {
        printf("back again!\n");
        return 0;
    } else {
        printf("first here.\n");
    }

    for (;;) {}
}

void handler(int s) {
    longjmp(buf, 1);
}

I compile it under VS 2012 on Windows 8 64bit. Every time I press Control+C, the program doesn't reboot as expected but stops working. Could anybody help me?

Upvotes: 0

Views: 310

Answers (2)

Arun Taylor
Arun Taylor

Reputation: 1572

I think what you want is this.

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

static int k;

void
handler(int s)
{
    k++;
}

int
main(int argc, char *argv[])
{
    int n = 0;

    signal(SIGINT, handler);

    while (1) {
        if (k > n) { 
            printf("handler got called %d\n", k);
            n = k;
            if (k == 5) {
                break; /* break out after five control-c */
            }
        }
    }

    exit(0);
}

Try it out and let me know how it goes.

Upvotes: 0

Jens Gustedt
Jens Gustedt

Reputation: 78943

From the current C standard:

If the signal occurs other than as the result of calling the abort or raise function, the behavior is undefined if the signal handler refers to any object with static or thread storage duration that is not a lock-free atomic object other than by assigning a value to an object declared as volatile sig_atomic_t, or the signal handler calls any function in the standard library other than the abort function, the _Exit function, the quick_exit function, or the signal function with the first argument equal to the signal number corresponding to the signal that caused the invocation of the handler.

you are using an object with static storage duration that is not in the list of allowed types (buf) and you use a function of the standard library that is not in the list of allowed functions (longjmp).

Upvotes: 2

Related Questions