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: getrlimitda 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 SIGKILLmandato 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 SIGXFSZdallo 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. opene gli amici sono appena tornati EMFILEal 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 waitstato.)
RLIMIT_ASe RLIMIT_DATAfarà solo malloc()e alcuni altri inizieranno a fallire (o riceveranno SIGSEGVse 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
SIGXCPUe 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 SIGKILLe SIGSEGVsono 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 ptracesu 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.)
mallocma sfortunatamente non risolve il problema di memoria in generale, perché in generale si tratta di una chiamata di sistemabrk(ho ragione?).