Ресурсы процессов не ограничены setrlimit
Я написал простую программу, ограничивающую размер данных до 65 КБ и проверяющую то же самое. Я выделяю фиктивную память размером более 65 КБ, и, если я делаю все правильно (как показано ниже), вызов malloc должен завершиться неудачно, не так ли?
#include <sys/resource.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
int main (int argc, char *argv[])
{
struct rlimit limit;
/* Get max data size . */
if (getrlimit(RLIMIT_DATA, &limit) != 0) {
printf("getrlimit() failed with errno=%d\n", errno);
return 1;
}
printf("The soft limit is %lu\n", limit.rlim_cur);
printf("The hard limit is %lu\n", limit.rlim_max);
limit.rlim_cur = 65 * 1024;
limit.rlim_max = 65 * 1024;
if (setrlimit(RLIMIT_DATA, &limit) != 0) {
printf("setrlimit() failed with errno=%d\n", errno);
return 1;
}
if (getrlimit(RLIMIT_DATA, &limit) != 0) {
printf("getrlimit() failed with errno=%d\n", errno);
return 1;
}
printf("The soft limit is %lu\n", limit.rlim_cur);
printf("The hard limit is %lu\n", limit.rlim_max);
system("bash -c 'ulimit -a'");
int *new2 = NULL;
new2 = malloc(66666666);
if (new2 == NULL)
{
printf("malloc failed\n");
return;
}
else
{
printf("success\n");
}
return 0;
}
Удивительно, но выходной сигнал выглядит примерно так:
The soft limit is 4294967295
The hard limit is 4294967295
The soft limit is 66560
The hard limit is 66560
core file size (blocks, -c) 0
data seg size (kbytes, -d) 65
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 14895
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 14895
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
success
Я делаю что-то неправильно? Пожалуйста, оставьте свой вклад. Спасибо!
2 ответа
Со страницы руководства setrlimit:
RLIMIT_DATA
Максимальный размер сегмента данных процесса (инициализированные данные, неинициализированные данные и куча). Это ограничение влияет на вызовы brk(2) и sbrk(2), которые завершаются ошибкой ENOMEM при обнаружении мягкого ограничения этого ресурса.
В частности, этот ресурс не относится к памяти, полученной через mmap
, внутренне malloc
использует различные механизмы для получения новой памяти. В этом случае вы обнаружите, что он использовал mmap
и не sbrk
или же brk
, Вы можете убедиться в этом, сбросив системные вызовы из вашей программы с помощью strace
,
Чтобы достичь того, что вы хотите, используйте RLIMIT_AS
ресурс вместо.
После исправления проблем с компиляцией кода.
Это код:
#include <sys/resource.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
int main ( void )
{
struct rlimit limit;
/* Get max data size . */
if (getrlimit(RLIMIT_DATA, &limit) != 0) {
printf("getrlimit() failed with errno=%d\n", errno);
exit( EXIT_FAILURE );
}
printf("The soft limit is %lu\n", limit.rlim_cur);
printf("The hard limit is %lu\n", limit.rlim_max);
limit.rlim_cur = 65 * 1024;
limit.rlim_max = 65 * 1024;
if (setrlimit(RLIMIT_DATA, &limit) != 0)
{
printf("setrlimit() failed with errno=%d\n", errno);
exit( EXIT_FAILURE );
}
if (getrlimit(RLIMIT_DATA, &limit) != 0)
{
printf("getrlimit() failed with errno=%d\n", errno);
exit( EXIT_FAILURE );
}
printf("The soft limit is %lu\n", limit.rlim_cur);
printf("The hard limit is %lu\n", limit.rlim_max);
system("bash -c 'ulimit -a'");
int *new2 = NULL;
new2 = malloc(66666666);
if (new2 == NULL)
{
printf("malloc failed\n");
exit( EXIT_FAILURE );
}
else
{
printf("success\n");
}
return 0;
}
и вот вывод:
The soft limit is 18446744073709551615
The hard limit is 18446744073709551615
The soft limit is 66560
The hard limit is 66560
bash: xmalloc: .././variables.c:2307: cannot allocate 48 bytes (16384 bytes allocated)
success
который указывает на изменения в rlimit работ, system
звонок был успешным, bash
команда не выполнена, и malloc
Был успешен.
Несколько прогонов одного и того же кода всегда выводят одинаковые значения, поэтому постоянное изменение значения rlimit не происходит
после запуска вышеуказанного кода несколько раз, оставив каждое окно терминала открытым, затем запустив bash
команда в еще одном окне терминала привела к следующему:
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 54511
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 54511
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
затем запустить код в еще одном терминале, затем запустить bash
Команда в том же терминале выводит точно такие же выходные значения.
Поэтому я подозреваю, что код использует неправильный подход к ограничению объема доступной памяти.