De um modo geral, acho que você não pode, infelizmente. (Alguns sistemas operacionais podem fornecer isso, mas não conheço os que conheço suportando isso.)
Documento de referência para limites de recursos: getrlimit
do POSIX 2008.
Tomemos, 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 rígido, obtém-se uma
SIGKILL
Se você pode wait()
no seu programa, você pode dizer se ele foi morto por SIGXCPU
. Mas você não pode diferenciar um SIGKILL
despachado por violação do limite rígido de uma simples e antiga matança de fora. Além do mais, se o programa lidar com isso XCPU
, você nem verá isso de fora.
A mesma coisa para RLIMIT_FSIZE
. Você pode ver a SIGXFSZ
partir do wait()
status se o programa não lidar com isso. Mas quando o limite de tamanho do arquivo é excedido, a única coisa que acontece é que mais E / S que tenta testar esse limite novamente simplesmente recebe EFBIG
- isso será tratado (ou não, infelizmente) pelo programa internamente. Se o programa funcionar SIGXFSZ
, o mesmo que acima - você não saberá.
RLIMIT_NOFILE
? Bem, você nem recebe sinal. open
e amigos apenas retornam EMFILE
ao programa. Caso contrário, não será incomodado, portanto falhará (ou não) da maneira que foi codificado para falhar nessa situação.
RLIMIT_STACK
? Bom velho SIGSEGV
, não pode ser distinguido da pontuação de outros motivos para ser entregue um. (Você saberá que foi isso que matou o processo, a partir do wait
status.)
RLIMIT_AS
e RLIMIT_DATA
apenas fará malloc()
e alguns outros começarão a falhar (ou receberão SIGSEGV
se o limite do AS for atingido ao tentar estender a pilha no Linux). A menos que o programa seja muito bem escrito, provavelmente falhará aleatoriamente nesse ponto.
Portanto, em resumo, geralmente, as falhas não são visivelmente diferentes de outros motivos de morte do processo, portanto, você não pode ter certeza ou pode ser tratado inteiramente a partir do programa, caso em que decide se / quando / como ocorre, não você de fora.
O melhor que você pode fazer, até onde eu sei, é escrever um pouco de código que bifurca seu programa, aguarda e:
- verifique o status de saída para detectar
SIGXCPU
e SIGXFSZ
(AFAIK, esses sinais serão gerados apenas pelo SO para problemas de limite de recurso). Dependendo das suas necessidades exatas, você pode assumir isso SIGKILL
e SIGSEGV
também estar relacionado aos limites de recursos, mas isso é um pouco exagerado.
- veja o que você pode obter
getrusage(RUSAGE_CHILDREN,...)
na sua implementação para obter uma dica sobre os outros.
Podem existir instalações específicas do sistema operacional para ajudar aqui (possivelmente coisas como ptrace
Linux ou Solaris dtrace
), ou possivelmente técnicas do tipo depurador, mas isso ficará ainda mais vinculado à sua implementação específica.
(Espero que outra pessoa responda com alguma coisa mágica que eu desconheço.)
malloc
mas infelizmente não resolve o problema de memória em geral, porque em geral trata-se de chamada do sistemabrk
(estou certo?).