代码之家  ›  专栏  ›  技术社区  ›  pa1

处理不受setrlimit限制的资源

  •  9
  • pa1  · 技术社区  · 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
    

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

    2 回复  |  直到 9 年前
        1
  •  6
  •   kaylum    9 年前

    setrlimit man page :

    RLIMIT_数据

    进程数据段的最大大小(已初始化 数据、未初始化数据和堆)。此限制影响呼叫 到brk(2)和sbrk(2),它们失败,错误为ENOMEM 遇到此资源的软限制。

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

    要实现您的目标,请使用 RLIMIT_AS 资源。

        2
  •  1
  •   user3629249    9 年前

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

    这是代码:

    #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值不会发生永久性更改

    在运行上述代码几次后,保持每个终端窗口打开,然后运行 猛击 另一个终端窗口中的命令导致以下结果:

    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
    

    然后在另一个终端中运行代码,然后运行 猛击 命令在同一终端输出完全相同的输出值。

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