1

I am running a C++ application on xubuntu and implemented a signal handler which handles SIGINT. My implementation should be fine, since it is working on all other machines (same OS) - except mine. "Working" means that the signal is received by a signal handler thread and a controlled shutdown is executed.

On my machine, ctrl+c just straight kills my application. No handling at all, only a "^C" on the console.

Does anyone have an idea why this behavior is machine dependent? Are there any setting I could check? Thanks.

EDIT: to see if it is related to the terminal ctrl+c behavior I tried kill -2 PID instead of ctrl+c : Same behavior, no handling on my machine, handling as expected on other machines.

Here is a code example of my signal handler:

std::atomic_bool shutdown_requested;

void SignalHandler() {
  sigset_t signal_set;
  sigemptyset(&signal_set);
  sigaddset(&signal_set, SIGTERM);
  sigaddset(&signal_set, SIGINT);
  while (!shutdown_requested) {
    int sig = SIGUNUSED;
    sigwait(&signal_set, &sig);
    switch (sig) {
      case SIGINT:
      case SIGTERM:
        shutdown_requested = true;
        break;
    }
  }
}

void SetSignalHandler() {
  sigset_t signals;
  sigfillset(&signals);
  pthread_sigmask(SIG_SETMASK, &signals, nullptr);
  std::thread(SignalHandler);
}

The atomic shutdown_requested signals the main thread to shut down. Any ideas?

spmmfycn
  • 21
  • 3
  • According to [man signal(7)](http://man7.org/linux/man-pages/man7/signal.7.html), SIGINT is 2. Did you try a `kill -2 PID` alternatively? I was in doubt whether Ctrl+C is handled in every shell/terminal identical and googled a bit. This may help: [SU: What to do when Ctrl + C can't kill a process?](https://superuser.com/a/243472) (This is actually the opposite question but the answers IMHO apply to your question as well.) – Scheff's Cat Nov 09 '18 at 09:23
  • Scheff brings up an important point - Ctrl+C may be configured in the terminal to send a different signal than SIGINT, and trying to reproduce it with `kill -2 PID` would determine if that may be the case. – Anya Shenanigans Nov 09 '18 at 09:26
  • Good point, I just tried kill -2 PID: Same behavior, no handling on my machine, handling as expected on other machines. This is really strange. I am starting to wonder if this has something to do with the multiple threads that are running. But then still it makes no sense that it is working fine on other machines. – spmmfycn Nov 09 '18 at 09:32
  • Threads and different behaviour on different machines smells to race conditions. Maybe if you post some code someone can see where is the problem. – LuisGP Nov 09 '18 at 10:44
  • @LuisGP I edited my post and added a code example. – spmmfycn Nov 09 '18 at 13:07
  • Do you call `SetSignalHandler` before any other thread is created? – Dark Falcon Nov 09 '18 at 16:27

1 Answers1

0

I wouldn't handle signals spawing a new thread, but I would rather just use signal() ( see "man 2 signal").

I guess that since you do not install a new signal handler with signal() (despite its name, your SignalHandler() is not a signal handler, it's just the execution loop of the thread), the default one remains active. On some systems your thread is faster and exits correctly, on other systems the default handler for SIGINT wins, and your application gets killed.

Perhaps, a different approach would be do disable signals on the process with sigprocmask(), but this would be quite an odd signal handling approach.

However I'm guessing. You example is not working - In case my guess is wrong, I'd suggest to prepare a MCVE as recommended in stackoverflow guidelines.

Sigi
  • 4,826
  • 1
  • 19
  • 23