Generally speaking, I don't think you can unfortunately. (Some operating systems might provide for it, but I'm not aware of the ones I know supporting this.)
Reference doc for resource limits:
getrlimit from POSIX 2008.
Take for example the CPU limit
- If the process exceeds the soft limit, it gets sent a
- If the process exceeds the hard limit, it gets a plain
If you can
wait() on your program, you could tell if it was killed by
SIGXCPU. But you could not differentiate a
SIGKILL dispatched for breach of the hard limit from a plain old kill from outside. What's more, if the program handles the
XCPU, you won't even see that from outside.
Same thing for
RLIMIT_FSIZE. You can see the
SIGXFSZ from the
wait() status if the program doesn't handle it. But once the file size limit is exceeded, the only thing that happens is that further I/O that attempts to test that limit again will simply receive
EFBIG - this will be handled (or not, unfortunately) by the program internally. If the program handles
SIGXFSZ, same as above - you won't know about it.
RLIMIT_NOFILE? Well, you don't even get a signal.
open and friends just return
EMFILE to the program. It's not otherwise bothered, so it will fail (or not) in whichever way it was coded to fail in that situation.
RLIMIT_STACK? Good old
SIGSEGV, can't be distinguished from the score of other reasons to get delivered one. (You will know that that was what killed the process though, from the
RLIMIT_DATA will just make
malloc() and a few others start to fail (or receive
SIGSEGV if the AS limit is hit while trying to extend the stack on Linux). Unless the program is very well written, it will probably fail fairly randomly at that point.
So in short, generally, the failures are either not visibly different from other process death reasons, so you can't be sure, or can be handled entirely from the program in which case it decides if/when/how it proceeds, not you from the outside.
The best you can do as far as I know is write a bit of code that forks of your program, waits on it, and:
- check the exit status to detect
SIGXFSZ (AFAIK, those signals will only be generated by the OS for resource limit problems). Depending on your exact needs, you could assume that
SIGSEGV were also related to resource limits, but that's a bit of a stretch.
- look at what you can get out of
getrusage(RUSAGE_CHILDREN,...) on your implementation to get a hint about the other ones.
OS-specific facilities might exist to help out here (possibly things like
ptrace on Linux, or Solaris
dtrace), or possibly debugger-type techniques, but that's going to be even more tied to your specific implementation.
(I'm hoping someone else will answer with some magic thing I'm completely unaware of.)