Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using the third parameter (void* context) of a sigaction handler with SIG_INFO results in a Segmentation Fault

I have reduced a huge fiber scheduler code that was producing the problem to the lines below.
What I expect is a clean return to the context, passed to the handler, every time.
What I get is "Handler. " printed out three times and then a Segmentation Fault.

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

ucontext_t currently_executed_context;

void handler_sigusr1(int signum, siginfo_t* siginfo, void* context)
{
    currently_executed_context = (*(ucontext_t*)context);

    printf("Handler. ");
    setcontext(&currently_executed_context);
}

int main()
{
    setbuf(stdout,0);

    struct sigaction action_handler;

    action_handler.sa_sigaction = handler_sigusr1;
    action_handler.sa_flags = SA_SIGINFO;

    sigaction(SIGUSR1,&action_handler,NULL);

    for(;;) { kill(getpid(),SIGUSR1); sleep(1); }

    return 0;
}

Used both gcc-4.4.3 and gcc-4.4.5 on two different Linux distributions.

like image 540
John Locke Avatar asked Mar 27 '13 17:03

John Locke


1 Answers

At this point, my own research of the problem can be provided as a partial answer.

Firstly, I've found this article, which is old and does not quote any official sources of information: http://zwillow.blogspot.com/2007/04/linux-signal-handling-is-broken.html. This is a relevant citation:

Second problem: You can't use setcontext() to leave signal handler and jump into another, previously saved, context. (Or, for that matter, you can't use it to return to the very same context passed as argument to the signal handler.) In other words, signal handler like

static void sighandler(
   int signo, siginfo_t *psi, void *pv)
{
  memcpy(puc_old, pv, sizeof(ucontext_t));
  /* choose another context to dispatch */
  setcontext(puc_another);
}

does not work. It does not restore signal mask specified in the puc_other, does not reestablish alternate signal stack, etc. However, this scheme works flawlessly on Solaris.

If somebody can confirm the part about Solaris, it would be appreciated.

Secondly, after speaking with a university lecturer, I've come to understand that setting/swapping a context from a signal handler is not as straight forward as doing so in other situations. Sadly, the person, who explained this to me could not provide further details at the time.

Thus, both of my sources do not seem entirely reliable, but are clues nonetheless.

like image 125
John Locke Avatar answered Sep 21 '22 20:09

John Locke