Взагалі кажучи, я, на жаль, не можу. (Деякі операційні системи можуть це забезпечити, але я не знаю тих, кого я знаю, що підтримують це.)
Довідковий документ щодо обмеження ресурсів: 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,...)
у своїй реалізації, щоб отримати підказку про інші.
Тут можуть існувати спеціальні засоби для ОС (можливо, такі речі, як ptrace
Linux або Solaris dtrace
), або, можливо, методи налагодження типу, але це буде ще більше пов'язане з вашою конкретною реалізацією.
(Я сподіваюся, що хтось інший відповість якоюсь магічною річчю, про яку я абсолютно не знаю.)
malloc
але, на жаль, це взагалі не вирішує проблему з пам'яттю, тому що загалом йдеться про системний викликbrk
(я прав?).