setitimer with ITIMER_VIRTUAL has no effect on 64-bit kernel
Originator: | Per.Mildner.usenet | ||
Number: | rdar://9336975 | Date Originated: | 26-Apr-2011 10:49 AM |
Status: | Closed | Resolved: | |
Product: | Mac OS X | Product Version: | 10.6.7 |
Classification: | Serious bug | Reproducible: | Always |
Summary: setitimer with ITIMER_VIRTUAL has no effect on 64-bit kernel Mac OS X 10.6.7. ITIMER_REAL works. Steps to Reproduce: See attached program. Expected Results: expect SIGVTALRM to happen, i.e. V is written by test program until interrupted by CTRL+C. Transcript from a machine (with 32-bit kernel) where it works as it should (real user name replaced with xxx): sekretariat:~ xxx$ gcc -version i686-apple-darwin10-gcc-4.2.1: no input files sekretariat:~ xxx$ gcc -Wall -Werror timer.c -o timer && ./timer VVVVVVVVVVVVVVVVVVVVVVVVV^C sekretariat:~ xxx$ uname -a Darwin sekretariat.local 10.7.0 Darwin Kernel Version 10.7.0: Sat Jan 29 15:17:16 PST 2011; root:xnu-1504.9.37~1/RELEASE_I386 i386 sekretariat:~ xxx$ date Tue Apr 19 16:29:09 CEST 2011 Actual Results: SIGVTALRM is never signalled, i.e. V is never written Transcript from failing machine (with 64-bit kernel): balrog:PrologTestFiles xxx$ gcc --version i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5664) Copyright (C) 2007 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. balrog:PrologTestFiles xxx$ gcc -Wall -Werror timer.c -o timer && ./timer ^C balrog:PrologTestFiles xxx$ uname -a Darwin balrog.local 10.7.0 Darwin Kernel Version 10.7.0: Sat Jan 29 15:16:10 PST 2011; root:xnu-1504.9.37~1/RELEASE_X86_64 x86_64 balrog:PrologTestFiles xxx$ date Di 19 Apr 2011 15:39:53 CEST Regression: This seems to work with 32-bit kernels. Running on a VMWare guest (Mac OS X Server 10.6.7) I can reproduce the problem when it boots with 64-bit kernel but the problem goes away when I reboot the same VMWare guest with a 32-bit kernel (even without recompiling the timer executable). Note that the above systems refer to real machines, not VMWare guests. Notes: This is a serious bug for us, even though there is a workaround (use 32-bit kernels), since our product (a programming language runtime) is embedded in our customers products and we have no way of informing the end users of the workaround. /* timer.c BEGIN */ /* This program demonstrates a bug where setitimer ITIMER_VIRTUAL does not seem to have any effect (seen on Mac OS X 10.6.7). [PM] Slightly modified from a program found on the net, originally written by Marc Feeley. Compile and run as gcc -Wall -Werror timer.c -o timer && ./timer it should write one V on stdout every 1/10 of a second. or gcc -DITIMER_SECS=1 timer.c -o timer && ./timer it should write one V on stdout about once every second. When the bug occurs the program just hangs. The program can be built to use ITIMER_REAL instead, with gcc -DUSE_ITIMER_REAL timer.c -o timer && ./timer this has not been seen to hang. */ #include <sys/time.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <errno.h> #ifndef ITIMER_SECS #define ITIMER_SECS 0 #endif #ifndef ITIMER_USECS #define ITIMER_USECS 100000 #endif /* ITIMER_USECS */ #define CHECK(EXPR) do{ \ if ((EXPR) == -1) { \ int e = errno; \ fprintf(stderr, "%s:%d ERROR errno=%d\n", \ __FILE__, (int)__LINE__, e); \ fflush(stderr); \ abort(); \ } \ } while (0) void heartbeat_interrupt_handler (int sig) { #ifdef USE_ITIMER_REAL write (STDOUT_FILENO, "R", 1); #else write (STDOUT_FILENO, "V", 1); #endif } int main (int argc, char *argv[]) { struct itimerval tv; int secs = ITIMER_SECS; int usecs = ITIMER_USECS; #ifdef USE_ITIMER_REAL int HEARTBEAT_ITIMER = ITIMER_REAL; int SIG = SIGALRM; #else int HEARTBEAT_ITIMER = ITIMER_VIRTUAL; int SIG = SIGVTALRM; #endif struct sigaction act; act.sa_handler = heartbeat_interrupt_handler; act.sa_flags = 0; CHECK(sigemptyset(&act.sa_mask)); CHECK(sigaction(SIG, &act, 0)); tv.it_interval.tv_sec = secs; tv.it_interval.tv_usec = usecs; tv.it_value.tv_sec = secs; tv.it_value.tv_usec = usecs; CHECK(setitimer(HEARTBEAT_ITIMER, &tv, 0)); for (;;) { /* keep CPU 100% busy */ } return 0; } /* timer.c END */
Comments
Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!