进程资源不受 setrlimit 限制

Processes resources not limited by setrlimit

我写了一个简单的程序来将它的数据大小限制为 65Kb 并验证我正在分配一个超过 65Kb 的虚拟内存并且逻辑上如果我做的都是正确的(如下所示)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

我有没有做错什么? 请放下您的输入。 谢谢!

纠正代码编译问题后。

这是代码:

#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 值

在 运行 上面的代码多次之后,同时让每个终端 window 打开,然后 运行 在另一个终端 window 中的 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 命令输出完全相同的输出值。

因此,我怀疑代码采用了错误的方法来限制可用内存量。

来自setrlimit man page

RLIMIT_DATA

The maximum size of the process's data segment (initialized data, uninitialized data, and heap). This limit affects calls to brk(2) and sbrk(2), which fail with the error ENOMEM upon encountering the soft limit of this resource.

具体来说,该资源不适用于通过 mmap 获得的内存。在内部 malloc 使用各种机制来获取新内存。在这种情况下,您会发现它使用 mmap 而不是 sbrkbrk。您可以通过使用 strace.

从程序中转储系统调用来验证这一点

要实现您想要的效果,请改用 RLIMIT_AS 资源。