Вообще говоря, я не думаю, что вы можете, к сожалению. (Некоторые операционные системы могут обеспечить это, но я не знаю, какие из них поддерживают это.)
Справочный документ по ограничениям ресурсов: getrlimit
с POSIX 2008.
Взять, к примеру, лимит процессора RLIMIT_CPU
.
- Если процесс превышает мягкое ограничение, он получает
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
(я прав?).LD_PRELOAD
ING , что это пограничное для «не модифицирующего процесса» ограничения, и это поможет немного, но на самом деле не -malloc
,brk
,sbrk
иmmap
будет завершатьсяENOMEM
, точно так , как если бы вы действительно были в ситуации низкой памяти (но намного ниже пределов памяти). Ограничение по времениRLIMIT_CPU
, я не знаю ограничения по времени настенных часов.brk
. Как я вижу, требование «программа не обрабатывает сигналы X, Y, Z ...» решит проблемы SIGXCPU, SIGXFSZ, SIGSEGV, благодаря waitpid (Если я ошибаюсь, пожалуйста, исправьте меня).brk
. Как я вижу, требование «программа не обрабатывает сигналы X, Y, Z ...» решит проблемы SIGXCPU, SIGXFSZ, SIGSEGV, благодаря waitpid. Я прав?В настоящее время я работаю над тем же вопросом. Я был в состоянии иметь частичное решение этого. Я использовал аудит системы . Вы можете отслеживать работу на [1].
[1] https://github.com/PaulDaviesC/Logging-limits.conf
источник