linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Signal delivery order
@ 2009-03-14 16:50 Gábor Melis
  2009-03-15  9:44 ` Oleg Nesterov
  0 siblings, 1 reply; 22+ messages in thread
From: Gábor Melis @ 2009-03-14 16:50 UTC (permalink / raw)
  To: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 953 bytes --]

(Please CC me, I'm not subscribed.)

Attached is a test program that tests the order in which synchronously 
triggered sigsegvs and pthread_kill() generated signals get delivered.

The test program triggers sigsegvs from a thread and tests whether the 
the sigsegv handler is invoked when the sigusr1 handler is already 
running. If that happens it exits with exit code 27. It seems that if 
the signal is sent by pthread_kill() and its signum is lower than that 
of sigsegv then it can be delivered before sigsegv. A normal kill does 
not seem to do this.

I would expect that no asynchronously generated signal (and here I 
include those sent by pthread_kill()) can overtake a sigsegv even if 
its signum is lower.

Reaching this diagnosis led me to an identical looking issue documented 
at: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4355769 .

Cheers,
Gabor Melis

PS: tested on x86 linux Debian Lenny, kernel: 2.6.26-1-686, glibc: 
2.7-18

[-- Attachment #2: signal-delivery-order.c --]
[-- Type: text/x-csrc, Size: 1960 bytes --]

#include <signal.h>
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/mman.h>
#include <sys/ucontext.h>
#include <unistd.h>

int test_signal;
int *page_address;
pthread_t tid;

int is_signal_blocked(int signum)
{
    sigset_t set;
    pthread_sigmask(SIG_BLOCK, 0, &set);
    return (sigismember(&set, signum));
}

void test_handler(int signal, siginfo_t *info, void *context)
{
}

void sigsegv_handler(int signal, siginfo_t *info, void *context)
{
    /* The test signal is blocked only in test_handler. */
    if (is_signal_blocked(test_signal)) {
        _exit(27);
    }
    mprotect(page_address, 4096, PROT_READ | PROT_WRITE);
}

void *make_faults(void *arg)
{
    while (1) {
        mprotect(page_address, 4096, PROT_NONE);
        *page_address = 1;
    }
}

void *reserve_page(void)
{
    int flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE;
    void *actual = mmap(0, 4096, PROT_NONE, flags, -1, 0);
    if (actual == MAP_FAILED) {
        perror("mmap");
        return 0;
    }
    return actual;
}

void install_handlers(void)
{
    struct sigaction sa;
    sa.sa_flags = SA_SIGINFO;
    sigemptyset(&sa.sa_mask);
    sa.sa_sigaction = test_handler;
    sigaction(test_signal, &sa, 0);
    sa.sa_sigaction = sigsegv_handler;
    sigaction(SIGSEGV, &sa, 0);
}

void test_with_pthread_kill()
{
    page_address = (int *)reserve_page();
    install_handlers();
    if (pthread_create(&tid, 0, make_faults, 0) < 0)
        perror("pthread_create");
    while(1) {
        pthread_kill(tid, test_signal);
    }
}

void test_with_kill()
{
    pid_t pid = fork();
    if (pid == 0) {
        page_address = (int *)reserve_page();
        install_handlers();
        make_faults(0);
    } else {
        while (1) {
            kill(pid, test_signal);
        }
    }
}

int main(void)
{
    test_signal = SIGUSR1;
    test_with_pthread_kill();
    /* Forking and kill()ing works as expected: */
    /* test_with_kill(); */
}

^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2009-03-18 15:23 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-03-14 16:50 Signal delivery order Gábor Melis
2009-03-15  9:44 ` Oleg Nesterov
2009-03-15 14:40   ` Gábor Melis
2009-03-15 17:29     ` Oleg Nesterov
2009-03-15 22:06       ` Gábor Melis
2009-03-16  0:28         ` Oleg Nesterov
2009-03-16  8:34           ` Gábor Melis
2009-03-16 21:13             ` Oleg Nesterov
2009-03-16 22:56               ` Chris Friesen
2009-03-17  4:13                 ` Q: SEGSEGV && uc_mcontext->ip (Was: Signal delivery order) Oleg Nesterov
2009-03-17  4:25                   ` Oleg Nesterov
2009-03-17  8:23                   ` Gábor Melis
2009-03-17  9:25                     ` Oleg Nesterov
2009-03-17 10:20                       ` Gábor Melis
2009-03-17 10:43                         ` Oleg Nesterov
2009-03-17 15:56                     ` Linus Torvalds
2009-03-17 19:20                       ` Q: SEGSEGV && uc_mcontext->ip David Miller
2009-03-18  9:58                       ` Q: SEGSEGV && uc_mcontext->ip (Was: Signal delivery order) Gábor Melis
2009-03-18  7:59                   ` Roland McGrath
2009-03-18  9:02                     ` RT signal queue overflow (Was: Q: SEGSEGV && uc_mcontext->ip (Was: Signal delivery order)) Gábor Melis
2009-03-18 14:52                       ` Linus Torvalds
2009-03-18 15:23                         ` Gábor Melis

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).