Взагалі кажучи, я, на жаль, не можу. (Деякі операційні системи можуть це забезпечити, але я не знаю тих, кого я знаю, що підтримують це.)
Довідковий документ щодо обмеження ресурсів: getrlimitвід POSIX 2008.
Візьмемо для прикладу ліміт процесора RLIMIT_CPU.
- Якщо процес перевищує м'який ліміт, йому надсилається a
SIGXCPU
- Якщо процес перевищує жорстку межу, він отримує звичайну
SIGKILL
Якщо ви можете wait()у своїй програмі, ви можете сказати, чи її вбив SIGXCPU. Але ви не змогли відрізнити SIGKILLвідправленого за порушення жорсткої межі від простого старого вбивства ззовні. Більше того, якщо програма обробляє програму XCPU, ви її навіть не побачите ззовні.
Те саме для RLIMIT_FSIZE. Ви можете бачити статус SIGXFSZзі wait()статусом, якщо програма його не обробляє. Але як тільки буде перевищено обмеження розміру файлу, єдине, що трапляється, це те, що подальший ввід / вивід, який намагається знову перевірити цей ліміт, просто отримає EFBIG- це буде оброблятися (чи ні, на жаль,) програмою внутрішньо. Якщо програма обробляє так SIGXFSZсамо, як вище, ви не будете знати про неї.
RLIMIT_NOFILE? Ну, ти навіть сигналу не отримуєш. openа друзі просто повертаються EMFILEдо програми. Інакше це не турбує, тому він зазнає невдачі (чи ні) тим, яким способом було б закодовано провал у цій ситуації.
RLIMIT_STACK? Старий добрий SIGSEGV, його не можна відрізнити від кількості інших причин, щоб його доставити. (Ви будете знати, що саме це вбило процес від waitстатусу.)
RLIMIT_ASі RLIMIT_DATAпросто зробить, malloc()а деякі інші почнуть виходити з ладу (або отримуватимуть, SIGSEGVякщо буде досягнуто обмеження AS, намагаючись розширити стек в Linux). Якщо програма не дуже добре написана, вона, ймовірно, вийде досить випадковим чином у цей момент.
Отже, коротко кажучи, як правило, збої або не помітно відрізняються від інших причин смерті процесу, тому ви не можете бути впевнені, або можете вирішуватись цілком з програми, і в цьому випадку він вирішує, чи / коли / як він проходить, а не ви ззовні.
Наскільки я знаю, ви можете написати трохи коду, який розщедрить вашу програму, чекає на неї та:
- перевірити стан виходу для виявлення
SIGXCPUта SIGXFSZ(AFAIK, ці сигнали будуть генеровані ОС лише для проблем з обмеженням ресурсів). В залежності від ваших конкретних потреб, можна припустити , що SIGKILLі SIGSEGVбули пов'язані з обмеженнями ресурсів, але це трохи розтягнути.
- подивіться на те, що ви можете отримати
getrusage(RUSAGE_CHILDREN,...)у своїй реалізації, щоб отримати підказку про інші.
Тут можуть існувати спеціальні засоби для ОС (можливо, такі речі, як ptraceLinux або Solaris dtrace), або, можливо, методи налагодження типу, але це буде ще більше пов'язане з вашою конкретною реалізацією.
(Я сподіваюся, що хтось інший відповість якоюсь магічною річчю, про яку я абсолютно не знаю.)
mallocале, на жаль, це взагалі не вирішує проблему з пам'яттю, тому що загалом йдеться про системний викликbrk(я прав?).