Hablando en general, no creo que puedas desafortunadamente. (Algunos sistemas operativos pueden proporcionarlo, pero no conozco los que sé que lo respaldan).
Documento de referencia para límites de recursos: getrlimit
de POSIX 2008.
Tomemos, por ejemplo, el límite de la CPU RLIMIT_CPU
.
- Si el proceso excede el límite flexible, se envía un
SIGXCPU
- Si el proceso excede el límite estricto, se obtiene un claro
SIGKILL
Si puede wait()
en su programa, podría decir si fue asesinado por SIGXCPU
. Pero no se podía diferenciar un SIGKILL
despacho por incumplimiento del límite estricto de una vieja matanza desde afuera. Además, si el programa maneja el XCPU
, ni siquiera lo verá desde afuera.
Lo mismo para RLIMIT_FSIZE
. Se puede ver la SIGXFSZ
del wait()
estado si el programa no manejarlo. Pero una vez que se excede el límite de tamaño de archivo, lo único que sucede es que más E / S que intente probar ese límite nuevamente simplemente recibirán EFBIG
, esto será manejado (o no, desafortunadamente) por el programa internamente. Si el programa maneja SIGXFSZ
, igual que el anterior, no lo sabrá.
RLIMIT_NOFILE
? Bueno, ni siquiera recibes una señal. open
y amigos acaban de regresar EMFILE
al programa. No se molesta de otra manera, por lo que fallará (o no) de cualquier manera que se codificó para fallar en esa situación.
RLIMIT_STACK
? Muy bien SIGSEGV
, no se puede distinguir de la puntuación de otras razones para obtener uno. (Sin embargo, sabrá que eso fue lo que mató el proceso, por el wait
estado).
RLIMIT_AS
y RLIMIT_DATA
solo se producirá malloc()
y algunos otros comenzarán a fallar (o recibirán SIGSEGV
si se alcanza el límite AS al intentar extender la pila en Linux). A menos que el programa esté muy bien escrito, probablemente fallará de manera bastante aleatoria en ese punto.
En resumen, en general, las fallas no son visiblemente diferentes de otras razones de muerte del proceso, por lo que no puede estar seguro o puede manejarse completamente desde el programa, en cuyo caso decide si / cuándo / cómo procede, no usted desde fuera.
Hasta donde sé, lo mejor que puede hacer es escribir un código que bifurca su programa, lo espera y:
- verifique el estado de salida para detectar
SIGXCPU
y SIGXFSZ
(AFAIK, esas señales solo serán generadas por el sistema operativo para problemas de límite de recursos). Dependiendo de sus necesidades exactas, podría suponer eso SIGKILL
y SIGSEGV
también estar relacionado con los límites de recursos, pero eso es un poco exagerado.
- mire lo que puede obtener de
getrusage(RUSAGE_CHILDREN,...)
su implementación para obtener una pista sobre los otros.
Es posible que existan recursos específicos del sistema operativo para ayudar aquí (posiblemente cosas como ptrace
en Linux o Solaris dtrace
), o posiblemente técnicas de tipo depurador, pero eso estará aún más vinculado a su implementación específica.
(Espero que alguien más responda con algo mágico que desconozco por completo).
malloc
pero desafortunadamente no resuelve el problema de memoria en general, porque en general se trata de una llamada al sistemabrk
(¿estoy en lo cierto?).LD_PRELOAD
ing que de límite para su "no modificar el proceso de" restricción, y va a ayudar un poco, pero no realmente -malloc
,brk
,sbrk
ymmap
fallará conENOMEM
, exactamente como si realmente estuviera en una situación de memoria baja (pero muy por debajo de los límites de memoria). El límite de tiempo esRLIMIT_CPU
, no sé de un límite de tiempo de reloj de pared.brk
. Como veo, el requisito 'el programa no maneja las señales X, Y, Z ...' resolverá los problemas de SIGXCPU, SIGXFSZ, SIGSEGV, gracias a waitpid (si estoy equivocado, corrígeme).brk
. Como veo, el requisito "el programa no maneja las señales X, Y, Z ..." resolverá los problemas de SIGXCPU, SIGXFSZ, SIGSEGV, gracias a waitpid. Estoy en lo cierto?Actualmente estoy trabajando en el mismo tema. He podido tener una solución parcial. He usado el subsistema de auditoría . Puedes seguir el trabajo en [1].
[1] https://github.com/PaulDaviesC/Logging-limits.conf
fuente