Ресурсы процессов не ограничены 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 Команда в том же терминале выводит точно такие же выходные значения.

Поэтому я подозреваю, что код использует неправильный подход к ограничению объема доступной памяти.

Другие вопросы по тегам