Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!seismo!rutgers!ucla-cs!heather From: heather@CS.UCLA.EDU Newsgroups: comp.bugs.4bsd Subject: Programs can thwart cpu time limit Message-ID: <6208@shemp.UCLA.EDU> Date: Sun, 24-May-87 13:44:45 EDT Article-I.D.: shemp.6208 Posted: Sun May 24 13:44:45 1987 Date-Received: Sun, 24-May-87 21:38:27 EDT Sender: root@CS.UCLA.EDU Reply-To: heather@CS.UCLA.EDU (Heather Burris) Distribution: world Organization: UCLA Computer Science Department Lines: 110 Keywords: cputime RLIMIT_CPU SIGXCPU I believe that the following behavior is a bug: I write a program that specifies a hard and a soft cpu time limit using the setrlimit() system call. I also use signal() to catch SIGXCPU signals (cpu time exceeded). What I expect to happen, based on the following quotes from the setrlimit manual page, is for the signal handler to get called when the soft limit is exceeded and for the program to be killed by the system when the hard limit is exceeded. (Quotes from 'man 2 setrlimit') "A resource limit is specified as a soft limit and a hard limit. When a soft limit is exceeded a process may receive a signal (for example, if the cpu time is exceeded), but it will be allowed to continue execution until it reaches the hard limit (or modifies its resource limit). ... " "A file I/O operation that would create a file that is too large will cause a signal SIGXFSZ to be generated; this nor- mally terminates the process, but may be caught. When the soft cpu time limit is exceeded, a signal SIGXCPU is sent to the offending process." (End quote) Instead what happens is that the the signal handler gets called once every 5 seconds from the time I hit the soft limit to the time I hit the hard limit (see line 144 of kern_clock.c for 5 second figure-- why isn't this documented). At that point, the signal handler is constantly called. I have attached a program which demonstrates that behavior after my signature. In addition, I found that a process could easily thwart an imposed cpu limit by simply declaring a signal handler for SIGXCPU, and doing all the calculations it wants to do in the signal handler itself. For example, instead of returning from the signal handler printsig() in the program below, I placed the line 'while (1);'. I found that program continued running indefinitely while accumulating cpu time. Does anyone have the fix to this bug? Or, I should ask first, is this not really a bug but rather a misunderstanding on my part about how the system is supposed to work? I'll wait for a while for a response and if no one has a fix, I'll try to fix it myself. Another question: I originally looked into the kernel cpu resource limitation code because of an unrelated problem: Users on our system have set very high cpu time limits (using csh) for programs that they want to run, yet find that their programs occassionally get killed with "Cputime limit exceeded" long before the limit they set could have passed. For example, setting a limit of 1,000,000 seconds should allow a program to run > 11 days but users have reported that their programs have been killed within a day. The limitation is set like this within the csh: (limit -h cputime 1000000; limit cputime 1000000; ) Both hard and soft limits are the same and the program does not try to catch SIGXCPU so the problem is really unrelated to the above bug description. Has anyone else experienced problems like this? Heather Burris Programmer, UCLA /* program whose signal handler will get called indefinitely */ #include #include #include #include printsig() { struct rlimit r; getrlimit(RLIMIT_CPU, &r); /* The following will print hardlimit, softlimit pairs of * (20, 10), (20, 15) and (20,20) 5 seconds apart and * then will quickly and constantly print (20,20) * indefinitely. */ fprintf(stderr, "Received signal, hardlimit %d, softlimit %d\n", r.rlim_max, r.rlim_cur); } main(argc, argv ) int argc; char **argv; { struct rlimit r; r.rlim_cur = 5; r.rlim_max = 20; setrlimit(RLIMIT_CPU, &r); getrlimit(RLIMIT_CPU, &r); fprintf(stderr, "Hardlimit %d, softlimit %d\n", r.rlim_max, r.rlim_cur); signal(SIGXCPU, printsig); while(1); } /* End of program */