De um modo geral, não acho que você possa, infelizmente. (Alguns sistemas operacionais podem fornecer isso, mas não estou ciente dos que eu conheço apoiando isso.)
Documento de referência para limites de recursos: getrlimit
do POSIX 2008.
Por exemplo, o limite da CPU RLIMIT_CPU
.
- Se o processo exceder o limite flexível, será enviado um
SIGXCPU
- Se o processo exceder o limite máximo, ele receberá uma
SIGKILL
Se você puder wait()
em seu programa, poderá dizer se ele foi eliminado por SIGXCPU
. Mas você não poderia diferenciar um SIGKILL
enviado para a violação do limite rígido de uma simples matança de fora. Além disso, se o programa lida com o XCPU
, você nem verá isso de fora.
Mesma coisa para RLIMIT_FSIZE
. Você pode ver o SIGXFSZ
do status wait()
se o programa não lidar com isso. Mas quando o limite de tamanho do arquivo for excedido, a única coisa que acontece é que mais E / S que tentam testar esse limite novamente receberão simplesmente EFBIG
- isso será tratado (ou não, infelizmente) pelo programa internamente. Se o programa lida com SIGXFSZ
, o mesmo que acima, você não saberá sobre isso.
RLIMIT_NOFILE
? Bem, você nem recebe um sinal. open
e amigos retornam EMFILE
para o programa. Não é de outro modo incomodado, por isso falhará (ou não) de qualquer forma que tenha sido codificado para falhar nessa situação.
RLIMIT_STACK
? O bom e velho SIGSEGV
, não pode ser distinguido da pontuação de outros motivos para receber um. (Você saberá que foi isso que matou o processo, a partir do status wait
.)
RLIMIT_AS
e RLIMIT_DATA
apenas farão malloc()
e alguns outros começarão a falhar (ou receber SIGSEGV
se o limite AS for atingido ao tentar estender a pilha no Linux). A menos que o programa esteja muito bem escrito, ele provavelmente falhará de forma bastante aleatória nesse ponto.
Portanto, em geral, as falhas não são visivelmente diferentes de outras causas de morte do processo, portanto você não pode ter certeza, ou pode ser tratado inteiramente a partir do programa, caso decida se / quando / como ele continua. não você do lado de fora.
O melhor que você pode fazer, tanto quanto eu sei, é escrever um pouco de código que garfos do seu programa, espera nele e:
- verifique o status de saída para detectar
SIGXCPU
eSIGXFSZ
(AFAIK, esses sinais serão gerados apenas pelo sistema operacional para problemas de limite de recursos). Dependendo de suas necessidades exatas, você pode assumir queSIGKILL
eSIGSEGV
também estavam relacionados a limites de recursos, mas isso é um pouco exagerado. - veja o que você pode obter de
getrusage(RUSAGE_CHILDREN,...)
em sua implementação para obter uma dica sobre os outros.
Recursos específicos do SO podem existir para ajudar aqui (possivelmente coisas como ptrace
no Linux ou Solaris dtrace
) ou, possivelmente, técnicas do tipo depurador, mas isso será ainda mais vinculado à sua implementação específica.
(Espero que alguém mais responda com alguma coisa mágica da qual eu esteja completamente inconsciente.)