Hi

I have an application which is creating generated code blocks in memory provided by mmap, once the application is running in the generated code blocks, it cannot be interrupted by a SIGALRM.

In the following example I generate a code section which simply performs an infinite loop (using an x86 jmp -2), whilst this code section is executing I expect a SIGALRM to be raised, and the appropriate handler to be called, however the handler never gets called, although the signal is raised.

I have run my program through strace and I see the signal being raised, but the handler never executes, here is a snippet from strace

...
41 17854 [itimer] testbad 3680 timer_thread: 0x610ECCE8 waiting for 999 ms
927712  945566 [itimer] testbad 3680 timer_thread: timed out
  102  945668 [itimer] testbad 3680 timer_thread: 0x610ECCE8 sending sig 14
45 945713 [itimer] testbad 3680 sig_send: sendsig 0x70C, pid 3680, signal 14, its_me 1 70 945783 [itimer] testbad 3680 sig_send: Not waiting for sigcomplete. its_me 1 signal 14 41 945824 [itimer] testbad 3680 sig_send: returning 0x0 from sending signal 14
   38  945862 [itimer] testbad 3680 timer_thread: looping
38 945900 [itimer] testbad 3680 timer_thread: 0x610ECCE8 waiting for 1000 ms
   53  945953 [sig] testbad 3680 sigpacket::process: signal 14 processing
   45  945998 [sig] testbad 3680 _cygtls::find_tls: sig 14
39 946037 [sig] testbad 3680 sigpacket::process: signal 14, about to call 0x401101
   40  946077 [sig] testbad 3680 setup_handler: suspending mainthread
81 946158 [sig] testbad 3680 interruptible: pc 0x3F0000, h 0x3F0000, interruptible 0 39 946197 [sig] testbad 3680 setup_handler: couldn't interrupt. trying again.
   49  946246 [sig] testbad 3680 setup_handler: suspending mainthread
52 946298 [sig] testbad 3680 interruptible: pc 0x3F0000, h 0x3F0000, interruptible 0 37 946335 [sig] testbad 3680 setup_handler: couldn't interrupt. trying again.
   43  946378 [sig] testbad 3680 setup_handler: suspending mainthread
...

If I replace my generated code section with a simple "for (;;);", then the testcase works as expected.

I attach the testcase below, in order to get the expected behavior, executing the "for(;;);" loop, simply compile in the following way
        gcc -o testok.exe test.c

to produce the failing behavior, make the testcase include the generated code section
        gcc -o testbad.exe test.c -DCG_LOOP

Code is as follows

//
// test.c
//
#include <sys/time.h>
#include <signal.h>
#include <stdio.h>
#include <sys/mman.h>

static int loop(void) {
    #if(CG_LOOP)
        static char *mem = 0;
        if(!mem) {
            mem = mmap(
                0,
                8192,
                PROT_READ|PROT_WRITE|PROT_EXEC,
                MAP_PRIVATE|MAP_ANONYMOUS,
                -1,
                0
            );
            // Generated Instruction : JMP 'to here'
            mem[0] = 0xeb;
            mem[1] = -2;
        }
        goto *mem;
    #else
        for(;;) {}
    #endif
}

static void setAlarm(int secs) {
    struct itimerval new;
    struct timeval time = {tv_sec:secs, tv_usec:0};
    new.it_value    = time;
    new.it_interval = time;
    setitimer(ITIMER_REAL, &new, 0);
}

static void sigalarmHandler(int signum, siginfo_t *sigInfo, void *context) {
    printf("Alarm handler called\n");
    setAlarm(1);
}

static void installAlarmHandler(void) {
    struct sigaction SIGALRM_Handler  = {{0}};
    SIGALRM_Handler.sa_sigaction = sigalarmHandler;
    SIGALRM_Handler.sa_flags     = SA_SIGINFO;
    sigfillset(&SIGALRM_Handler.sa_mask);
    sigaction(SIGALRM, &SIGALRM_Handler, 0);
}

int main() {
    installAlarmHandler();
    setAlarm(1);
    loop();
    return 1;
}



--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

Reply via email to