[BUG] bad uc_stack passed to signal handlers

From: Andrew Hastings
Date: Tue May 22 2007 - 16:53:25 EST


I'm experimenting with remapping the stack to hugepages. I was hoping
to use the Posix getcontext, sigaltstack, and sigaction interfaces to do
this. Unfortunately, the GNU/Linux implementations are not working as
specified by Posix.

Omitting error checks, here's what I'm doing:

ucontext_t main_uc;

main()
{
...
getcontext(&main_uc);
alt.ss_sp = malloc(alt.ss_size = SIGSTKSZ);
alt.ss_flags = 0;
sigaltstack(&alt, (stack_t *)0);
sigemptyset(&set);
act.sa_sigaction = handler;
act.sa_mask = set;
act.sa_flags = SA_ONSTACK|SA_SIGINFO;
sigaction(SIGUSR1, &act, (struct sigaction *)0);
raise(SIGUSR1);
}

void handler(int sig, siginfo_t *i, void *c)
{
ucontext_t *ucp = (ucontext_t *)c;
...

According to Posix, ucp->uc_stack should "refer to the receiving
thread's context that was interrupted when the signal was delivered."

However, Linux always sets it to the sigaltstack. (Even if SA_ONSTACK
was not specified, in which case ucp->uc_stack points to a stack that
has nothing to do with the running signal handler nor the context that
was active when the signal was received.)

FWIW, I ran on Linux 2.6.16.27-0.9-smp x86_64 and Linux
2.6.16.27-0.6-default i386, but the code is the same in linux-2.6.22-rc1
and all the architectures I inspected seem to have this same bug
in setup_rt_frame.

I was hoping to work around this with getcontext, but it appears to be
incompletely implemented, and does not set the main_uc.uc_stack field.
There's a two-year-old bug report against glibc:
http://sources.redhat.com/bugzilla/show_bug.cgi?id=759

Reading the Posix specification, I would expect the values inside
main_uc.uc_stack and ucp->uc_stack to be identifical. Making Linux and
glibc agree on these values would probably require turning getcontext
into a system call.

-Andrew Hastings
Cray Inc.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/