SIGALRM is ignored in generated code blocks (using mmap) - testcase included

Lee Moore moorel@ntlworld.com
Mon Jan 23 12:21:00 GMT 2006


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/



More information about the Cygwin mailing list