9

我编写了一个简单的程序来将它的数据大小限制为 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

我做错了什么吗?请放弃您的输入。谢谢!

4

2 回答 2

6

setrlimit 手册页

RLIMIT_DATA

进程数据段的最大大小(初始化数据、未初始化数据和堆)。此限制会影响对 brk(2) 和 sbrk(2) 的调用,它们会在遇到此资源的软限制时失败并返回错误 ENOMEM。

具体来说,该资源不适用于通过mmap. 在内部malloc使用各种机制来获取新内存。在这种情况下,您会发现它 usedmmap而不是sbrkor brk。您可以通过使用 .dump 从您的程序中转储系统调用来验证这一点strace

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

于 2015-12-28T06:38:02.227 回答
1

在纠正了代码编译的问题之后。

这是代码:

#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在同一终端中运行命令输出完全相同的输出值。

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

于 2015-12-28T06:34:03.970 回答