1

Can we force quit a C program's execution after a fraction of seconds (range of milliseconds) or by the size of memory it uses? This way, I want to restrict printing content in an infinite loop and restrict buffer overruns.

I am using cygwin GCC4.3 compiler and want to implement it as a tool in PHP, which takes in the C source as input and displays the corresponding output.

PS - 1. I say milliseconds because my C problems will only involve very simple arithmetic/computations. 2. To restrict the execution time, set_time_limit()in php would restrict the entire PHP script's execution time and not the time allotted to exec( )

Ankit Mittal
  • 1,330
  • 2
  • 9
  • 11

4 Answers4

2

You might want to investigate whether your system has nanosleep() from POSIX 2008. Note that even if you can specify a time in nanoseconds, the system may not be able to honour sub-millisecond timings very reliably.

You might find that µ-sleep() (spelled usleep()) is available instead, though it is officially obsolete. It specifies a time including microseconds. A quick search on Google for 'usleep windows' suggests Sleep() as a native Windows alternative.

See also: Sleep less than one millisecond.

See also: Command line command to auto-kill a command after a certain amount of time. The program there is not currently written to deal with sub-second timing, but the necessary adaptations would not be very hard once you've decided on the sub-second timing interface to use.

Community
  • 1
  • 1
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
1

You should be able to use the alarm() function. While it is found in unistd.h it is a POSIX.1-2001 function and should be available under cygwin. If SIGALRM is not handled it kills the process.

Try it:

#include <stdio.h>
#include <unistd.h>

int main() {

     alarm(5); /* raise alarm after 5 seconds */
     
     while(1) {
             printf("Running forever\n");
     }
     return 0; /* never reached */
}

update

As jonathan points out alarm(2) only works in seconds so you can use setitimer instead (also POSIX compliant)

#include <stdio.h>
#include <sys/time.h>

int main() {

     /* --CUT HERE-- */
     struct itimerval timer;
     timer.it_value.tv_sec = 0;
     timer.it_value.tv_usec = 5000; /* 5 milliseconds */
     timer.it_interval.tv_sec = 0;
     timer.it_interval.tv_usec = 0; 

     setitimer(ITIMER_REAL, &timer, NULL);
     /* --END CUT-- */
     while(1) {
             printf("Running forever\n");
     }
     return 0; /* never reached */
}

if the above works on your system, copy code from --CUT HERE-- to --END CUT-- and paste it into your main;

update 2

to limit memory try using setrlimit:

see Set stack size with setrlimit() and provoke a stack overflow/segfault

for an example

Community
  • 1
  • 1
Ahmed Masud
  • 21,655
  • 3
  • 33
  • 58
  • 1
    Except that `alarm()` works in units of thousands of milliseconds (aka 'seconds')... – Jonathan Leffler Feb 10 '12 at 06:51
  • @Ahmed MAsud running a infinite loop gcc make a .exe file in fraction of second. but problem occur when I try to read .exe it run forever. – Ankit Mittal Feb 10 '12 at 06:56
  • @JonathanLeffler thanks for pointing that out jonathan, fixed – Ahmed Masud Feb 10 '12 at 07:00
  • @ankit ... when you run the program, you will see that it runs for just the number of seconds you set in the setitimer. put the code without the while(1) loop in the beginning of your main and run the software. – Ahmed Masud Feb 10 '12 at 07:02
  • @JonathanLeffler Thanks to giving me the answer I got a lot of hint, can I also restrict the memory used by a program? please answer if you have? – Ankit Mittal Feb 10 '12 at 07:11
  • @AhmedMasud Thanks to giving me the answer I got a lot of hint, can I also restrict the memory used by a program? please answer if you have? – Ankit Mittal Feb 10 '12 at 07:11
  • @AhmedMasud I m using windows and setrlimit() work on linux please tell me some thing which can be in windows. and the solution of problem at OS level or PHP script level, because I do not want to change the C program as user written – Ankit Mittal Feb 10 '12 at 07:38
  • well at the OS level you can actually set process limits .. http://stackoverflow.com/questions/192876/set-windows-process-or-user-memory-limit has a good discussion on it – Ahmed Masud Feb 10 '12 at 07:56
  • @AhmedMasud I read that but it is not helpful for restrict C program, as I want – Ankit Mittal Feb 10 '12 at 08:26
0

I have done something similar in past, and the architecture I used was - Have a parent C-program say main.c, code similar to below (note this is no way a production code, and not even guarantee to compile, the code below is only for the purpose of demonstration).

// ---------------------- main.c ----------------
int main_child(); // the body is defined in "your_test_source.c"

int main()
{
  pthread_t tid;

  // create child thread
  pthread_create(tid, NULL, main_child, NULL);

  // start monitoring the child thread
  // ...
  // you can kill child thread by calling pthread_exit
  // and check for memory usage by system calls.

  return 0;
}

#define main main_child
  // we change the main function to main_child
  #include "your_test_source.c"
#undef main
// ---------------------- end -------------

your_test_source.c - this is the test file.

This adds up a layer for you to compile and debug, but it works.

BenMorel
  • 34,448
  • 50
  • 182
  • 322
hack_tick
  • 161
  • 2
  • 10
  • ok it create a child thread but still the problem is not solved of infinite loop and more memory consumption and I do not want to change in code. I want to restrict it at Compile time or by the PHP – Ankit Mittal Feb 10 '12 at 07:15
0

To limit the size of memory just do not use dynamic memory allocation or recursion. You can then ensure that the memory requirements are bounded (that is the coding standard for safety critical systems).

As to time requirements, why just live with the limitation of seconds granualarity and limit execution to one second?

Ed Heal
  • 59,252
  • 17
  • 87
  • 127
  • Actually I want to check all these thing at the time of compilation and program can be contain any thing, I do not want to restrict it. – Ankit Mittal Feb 10 '12 at 07:41
  • You cannot limit the time of execution at compile time. That is impossible since when executing the program, the time of execution depends on what else the processor/disk/memory is doing. But you can put an upper limit on the memory requirements as described above. – Ed Heal Feb 10 '12 at 08:21
  • can you tell me how to set upper limit on memory of a C progarm – Ankit Mittal Feb 10 '12 at 09:14
  • @Ankit - If you do not use dynamic allocation and recursion there is a maximum limit i.e. the stack will not just grow and grow. Heap is not used. This is due to the call stack has an upper limit and that implies that the amount of local variables has an upper limit. If you wish you can find out all the possible call stacks and hence work out the upper limit. – Ed Heal Feb 10 '12 at 10:22