In generale, non penso che tu possa purtroppo. (Alcuni sistemi operativi potrebbero provvedere, ma non sono a conoscenza di quelli che conosco supportando questo.)
Documento di riferimento per i limiti delle risorse: getrlimit
da POSIX 2008.
Prendiamo ad esempio il limite della CPU RLIMIT_CPU
.
- Se il processo supera il limite software, viene inviato a
SIGXCPU
- Se il processo supera il limite massimo, diventa chiaro
SIGKILL
Se puoi wait()
sul tuo programma, potresti dire se è stato ucciso da SIGXCPU
. Ma non potevi differenziare un SIGKILL
mandato per violazione del limite rigido da una vecchia uccisione normale dall'esterno. Inoltre, se il programma gestisce il XCPU
, non lo vedrai nemmeno dall'esterno.
Stessa cosa per RLIMIT_FSIZE
. Puoi vedere SIGXFSZ
dallo wait()
stato se il programma non lo gestisce. Ma una volta superato il limite della dimensione del file, l'unica cosa che succede è che ulteriori I / O che tentano di testare nuovamente quel limite riceveranno semplicemente EFBIG
- questo sarà gestito (o sfortunatamente) dal programma internamente. Se il programma gestisce SIGXFSZ
, come sopra - non lo saprai.
RLIMIT_NOFILE
? Bene, non ricevi nemmeno un segnale. open
e gli amici sono appena tornati EMFILE
al programma. Altrimenti non è disturbato, quindi fallirà (o meno) in qualunque modo sia stato programmato per fallire in quella situazione.
RLIMIT_STACK
? Buon vecchio SIGSEGV
, non si può distinguere dal punteggio di altri motivi per essere consegnato uno. (Saprai che quello è stato ciò che ha ucciso il processo dallo wait
stato.)
RLIMIT_AS
e RLIMIT_DATA
farà solo malloc()
e alcuni altri inizieranno a fallire (o riceveranno SIGSEGV
se il limite AS viene raggiunto mentre si tenta di estendere lo stack su Linux). A meno che il programma non sia scritto molto bene, probabilmente a quel punto fallirà in modo abbastanza casuale.
Quindi in breve, in generale, i guasti non sono visibilmente diversi dagli altri motivi di morte del processo, quindi non si può essere sicuri, o possono essere gestiti interamente dal programma nel qual caso decide se / quando / come procede, non tu da fuori.
Il meglio che puoi fare per quanto ne so è scrivere un po 'di codice che forks del tuo programma, aspetta su di esso e:
- controllare lo stato di uscita per rilevare
SIGXCPU
e SIGXFSZ
(AFAIK, quei segnali saranno generati dal sistema operativo solo per problemi di limite delle risorse). A seconda delle vostre esigenze, si potrebbe supporre che SIGKILL
e SIGSEGV
sono stati anche in relazione ai limiti di risorse, ma questo è un po 'di un tratto.
- guarda cosa puoi ottenere dalla
getrusage(RUSAGE_CHILDREN,...)
tua implementazione per avere un suggerimento sugli altri.
Potrebbero esistere strutture specifiche del sistema operativo per aiutare qui (forse cose come ptrace
su Linux o Solaris dtrace
), o forse tecniche di tipo debugger, ma questo sarà ancora più legato alla tua specifica implementazione.
(Spero che qualcun altro risponda con qualcosa di magico di cui non sono completamente a conoscenza.)
malloc
ma sfortunatamente non risolve il problema di memoria in generale, perché in generale si tratta di una chiamata di sistemabrk
(ho ragione?).