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

在valgrind下运行时,setrlimit失败,不允许操作

  •  14
  • asio_guy  · 技术社区  · 6 年前

    我可能遗漏了什么,也可能不是,但是 setrlimit 在valgrind下运行时,函数始终失败

    int main()
    {
            const struct rlimit file_limits = { .rlim_cur = 65536, .rlim_max = 65536 };
            if ( setrlimit( RLIMIT_NOFILE, &file_limits ) )
            {
                    printf(" Failed  %d", errno );
                    perror(" More " );
            }
            else
            {
                    printf(" Success ");
            }
            printf("\n");
            return 0;
    }
    

    以下是运行示例

    正常运行

    sh-4.2# ulimit -H -n
    800000
    sh-4.2# ulimit -S -n
    500000
    sh-4.2# ./rlimit
     Success
    sh-4.2#
    

    sh-4.2#
    sh-4.2# valgrind ./rlimit
    ==28974== Memcheck, a memory error detector
    ==28974== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
    ==28974== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
    ==28974== Command: ./rlimit
    ==28974==
     More : Operation not permitted
     Failed  1
    ==28974==
    ==28974== HEAP SUMMARY:
    ==28974==     in use at exit: 0 bytes in 0 blocks
    ==28974==   total heap usage: 1 allocs, 1 frees, 568 bytes allocated
    ==28974==
    ==28974== All heap blocks were freed -- no leaks are possible
    ==28974==
    ==28974== For counts of detected and suppressed errors, rerun with: -v
    ==28974== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
    sh-4.2#
    

    任何关于这方面的提示都会很好。 这是CentOS 7.4版(最终版)。

    使用最少的工作代码:

    int main()
    {
            const struct rlimit file_limits = { .rlim_cur = 65536, .rlim_max = 65536 };
            setrlimit( RLIMIT_NOFILE, &file_limits ) ;
            perror(" wrong ?? " );
            printf("\n");
            return 0;
    }
    

    相应输出:

    [root@localhost kk]# valgrind ./rlimit
    ==29179== Memcheck, a memory error detector
    ==29179== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
    ==29179== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
    ==29179== Command: ./rlimit
    ==29179==
     wrong ?? : Operation not permitted
    
    ==29179==
    ==29179== HEAP SUMMARY:
    ==29179==     in use at exit: 0 bytes in 0 blocks
    ==29179==   total heap usage: 1 allocs, 1 frees, 568 bytes allocated
    ==29179==
    ==29179== All heap blocks were freed -- no leaks are possible
    ==29179==
    ==29179== For counts of detected and suppressed errors, rerun with: -v
    ==29179== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
    [root@localhost kk]# ./rlimit
     wrong ?? : Success
    

    错??:不允许操作 快把我逼疯了:(

    因此,根据一些建议,我试图检索现有的限制,看看是否有什么不对劲,结果发现行为超出了我的理解

    int main()
    {
            const struct rlimit file_limits = { .rlim_cur = 65536, .rlim_max = 65536 };
            struct rlimit limit;
            getrlimit(RLIMIT_NOFILE,&limit);
            printf("%d \n",limit.rlim_max);
    
            setrlimit( RLIMIT_NOFILE, &file_limits ) ;
            perror(" wrong ?? " );
            printf("\n");
    
            getrlimit(RLIMIT_NOFILE,&limit);
            printf("%d \n",limit.rlim_max);
            return 0;
    }
    

    第一次运行时,limit设置为65590,可执行文件能够将limits更改为65536

    [root@localhost kk]# ulimit -n
    65590
    [root@localhost kk]# ./rlimit
    65590
     wrong ?? : Success
    
    65536
    [root@localhost kk]#
    

    第二次运行,在valgrind下

    [root@localhost kk]# ulimit -n
    65590
    [root@localhost kk]# valgrind ./rlimit
    ==17595== Memcheck, a memory error detector
    ==17595== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
    ==17595== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
    ==17595== Command: ./rlimit
    ==17595==
    65578
     wrong ?? : Operation not permitted
    
    65578
    ==17595==
    ==17595== HEAP SUMMARY:
    ==17595==     in use at exit: 0 bytes in 0 blocks
    ==17595==   total heap usage: 1 allocs, 1 frees, 568 bytes allocated
    ==17595==
    ==17595== All heap blocks were freed -- no leaks are possible
    ==17595==
    ==17595== For counts of detected and suppressed errors, rerun with: -v
    ==17595== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
    [root@localhost kk]#
    

    我可能倾向于说,maybeavalgrind为它保留了一些文件描述符 based on discussion here 假设这个案子是12??因此将限制设置为65578??这比该计划试图保留的65536还要多。

    还有什么建议吗?

    2 回复  |  直到 6 年前
        1
  •  3
  •   phd    6 年前

    fd 0的允许范围。。硬极限, i、 e.量程硬极限-11。。硬极限, 然后模拟一个新的硬极限,即硬极限-12。

    然后禁止来宾应用程序更改这个(模拟的)硬限制。 下面是一段处理setrlimit模拟的代码:

     if (((struct vki_rlimit *)(Addr)ARG2)->rlim_cur > VG_(fd_hard_limit) ||
          ((struct vki_rlimit *)(Addr)ARG2)->rlim_max != VG_(fd_hard_limit)) {
         SET_STATUS_Failure( VKI_EPERM );
      }
    

    如您所见,如果提供的rlim_max与模拟的VG_(fd_hard_limit)不同,valgrind会使setrlimit失败。 接受后,valgrind将更改模拟软限制。

    我不太明白为什么上面的代码没有 我认为这是因为使用了这个(不可更改的)VG(fd\U硬极限) 通过valgrind找到valgrind保留FD和

    要绕过这个问题,你应该得到限制,然后只改变 软限制低于硬限制,因为更改硬限制将 被valgrind setrlimit模拟拒绝。

        2
  •  0
  •   ks1322    6 年前

    这似乎是瓦尔格林的局限之一,也就是他的局限 setrlimit 用于在Valgrind下运行时的硬限制。见 news for release 2.1.2

    • 另外,对文件描述符实现一个模拟的软限制 到目前的保留区,这实际上是一个硬的 限制尽可能好-硬限制不允许移动 停止软限制的减少,导致在 尝试从保留区域分配描述符(这个 实际上来自bug(83998)。

    github issue 例如。