D'une manière générale, je ne pense pas que vous puissiez malheureusement. (Certains systèmes d'exploitation peuvent le prévoir, mais je ne connais pas ceux que je connais qui prennent cela en charge.)
Doc de référence pour les limites de ressources: à getrlimit
partir de POSIX 2008.
Prenons par exemple la limite CPU RLIMIT_CPU
.
- Si le processus dépasse la limite souple, il reçoit un message
SIGXCPU
- Si le processus dépasse la limite stricte, il obtient un simple
SIGKILL
Si vous le pouvez wait()
sur votre programme, vous pouvez savoir s'il a été tué par SIGXCPU
. Mais vous ne pouviez pas différencier un SIGKILL
envoyé pour violation de la limite stricte d'un ancien meurtre ordinaire de l'extérieur. De plus, si le programme gère le XCPU
, vous ne le verrez même pas de l'extérieur.
Même chose pour RLIMIT_FSIZE
. Vous pouvez voir le à SIGXFSZ
partir de l' wait()
état si le programme ne le gère pas. Mais une fois la limite de taille de fichier dépassée, la seule chose qui se produit est que les E / S supplémentaires qui tentent de tester à nouveau cette limite recevront simplement EFBIG
- cela sera géré (ou non, malheureusement) par le programme en interne. Si le programme gère SIGXFSZ
, comme ci-dessus - vous ne le saurez pas.
RLIMIT_NOFILE
? Eh bien, vous ne recevez même pas de signal. open
et les amis reviennent EMFILE
au programme. Ce n'est pas gêné autrement, donc il échouera (ou non) de la manière dont il a été codé pour échouer dans cette situation.
RLIMIT_STACK
? Bon vieux SIGSEGV
, ne peut pas être distingué de la vingtaine d'autres raisons de se faire livrer. (Vous saurez que c'est ce qui a tué le processus, d'après le wait
statut.)
RLIMIT_AS
et RLIMIT_DATA
va juste faire malloc()
et quelques autres commencent à échouer (ou à recevoir SIGSEGV
si la limite AS est atteinte en essayant d'étendre la pile sous Linux). À moins que le programme ne soit très bien écrit, il échouera probablement de manière assez aléatoire à ce stade.
Donc, en bref, généralement, les échecs ne sont pas visiblement différents des autres raisons de mort du processus, vous ne pouvez donc pas être sûr ou peuvent être entièrement gérés à partir du programme, auquel cas il décide si / quand / comment cela se déroule, pas vous de l'exterieur.
Pour autant que je sache, le mieux que vous puissiez faire est d'écrire un peu de code qui bifurque votre programme, attend dessus et:
- vérifier l'état de sortie à détecter
SIGXCPU
et SIGXFSZ
(AFAIK, ces signaux ne seront générés par le système d'exploitation que pour les problèmes de limite de ressources). En fonction de vos besoins exacts, vous pouvez supposer cela SIGKILL
et SIGSEGV
étaient également liés aux limites de ressources, mais c'est un peu exagéré.
- regardez ce que vous pouvez retirer de
getrusage(RUSAGE_CHILDREN,...)
votre implémentation pour obtenir un indice sur les autres.
Des fonctionnalités spécifiques au système d'exploitation peuvent exister pour vous aider ici (peut-être des choses comme ptrace
sous Linux ou Solaris dtrace
), ou éventuellement des techniques de type débogueur, mais cela va être encore plus lié à votre implémentation spécifique.
(J'espère que quelqu'un d'autre répondra avec quelque chose de magique que je ne connais pas du tout.)
malloc
mais malheureusement cela ne résout pas le problème de mémoire en général, car en général il s'agit d'un appel systèmebrk
(ai-je raison?).