我可能缺少某些东西,但是可能没有,但是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#
在valgrind下
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;
}
第一次运行,将限制设置为65590,可执行文件可以将限制更改为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]#
我可能倾向于说valgrind会保留一些文件描述符供其使用based on discussion here,在这种情况下,它是12?因此将限制设置为65578?该程序尝试保留的65536内容还更多。
还有其他建议吗?
答案 0 :(得分:3)
在fd 0 .. hard_limit的允许范围内, valgrind在范围的末尾为自己的目的保留一组fd 即范围hard_limit-11 .. hard_limit, 然后模拟一个新的硬限制,即hard_limit-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_hard_limit)。 我认为这是因为使用了此(不可更改)VG_(fd_hard_limit) 通过valgrind查找valgrind保留的fds与 来宾fds。
要绕过该问题,您应该获得限制,然后才进行更改 软限制低于硬限制,因为更改硬限制将 被valgrind setrlimit模拟拒绝。
答案 1 :(得分:0)
这似乎是Valgrind的限制之一,即在Valgrind下运行时,硬限制的限制为setrlimit
。参见news for release 2.1.2:
- 对文件描述符实施仿真的软限制 到当前的保留区,实际上是硬地 限制。 setrlimit系统调用现在只需更新仿真的 极限越好-硬极限不允许移动 根本没有,如果您尝试更改它,则只返回EPERM。这应该 在valgrind时停止软限制的减少导致断言 尝试从保留区域分配描述符。 (这个 实际上来自错误#83998)。
请注意,您不是唯一一个达到Valgrind限制的人,例如,请参见此github issue。