Pat
Pat

Reputation: 2022

gdb changing the value of sigint as caught by sigwait in a handler thread?

I have a multithreaded (pthreads) application where I have hooked SIGINT to allow me to interrupt the program. I set up a signal hander thread like so:

    /*** startup code ***/
// Prep signal-related stuff:
signal(SIGPIPE, SIG_IGN);

sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGINT);
assert(0 == pthread_sigmask(SIG_BLOCK, &set, NULL));

// Spawn signal handling thread
pthread_t sig_pthread;
pthread_create(&sig_pthread, NULL, &sig_thread, (void *) &set);

The signal handler thread is here:

static void* sig_thread(void *arg) {
    sigset_t *set = (sigset_t *) arg;
    int s, sig;

#ifndef __APPLE__
    prctl(PR_SET_NAME, "signal hander", 0, 0, 0);
#endif

    for (;;) {
        s = sigwait(set, &sig);
        if (s != 0) {
            ERR(E_UNKNOWN, "sigwait failed?\n");
            /* ERR is macro -> exit(E_UNKNOWN) */
        }

        if (sig == SIGINT) {
            ...
        } else {
            ERR(E_UNKNOWN, "caught unknown signal %d\n", sig);
            /* ERR is macro -> exit(E_UNKNOWN) */
        }
    }
}

When running normally, the code works as expected. However, if I run the program under gdb, I get:

--- E: caught unknown signal 4611

Does anyone have any insight on the (decimal) value 4611 (0x1203, 01103)? It was not anything obvious in signal.h. Does anyone know what gdb is doing to cause this to happen and how I can fix / prevent it?

Upvotes: 1

Views: 300

Answers (1)

alk
alk

Reputation: 70971

I suspect the 4611 to be garbage, as you do not initialise sig prior to calling sigwait().

From the sources you show, it seems like you do not skip the test of sig in case of an error (s != 0).

You might like to mod your code like so:

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

#define E_UNKNOWN "E"
#define ERR(ec, fmt, ...) (fprintf(stderr, "--- %s: " fmt, (ec), __VA_ARGS__))

...

  for (;;) {
    int sig = 0;
    int s = sigwait(set, &sig);

    if (s != 0) {
        ERR(E_UNKNOWN, "sigwait() failed with %d.\n", s);
    }
    else {
      if (sig == SIGINT) {
          ...
      } else {
        ERR(E_UNKNOWN, "Caught unhandled signal %d.\n", sig);
      }
    }
    ...

Upvotes: 1

Related Questions