我有一个相当健壮的C++库CI测试,这些测试(大约50个)运行在相同的Docker映像上,但在不同的机器上。
在一台机器(“A”)中,所有memcheck(valgrind)测试均通过(即没有内存泄漏)。在另一台机器(“B”)中,* 所有 * 测试均产生以下相同的valgrind错误。
51/56 MemCheck #51: combinations.cpp.x ....................***Exception: SegFault 0.14 sec
valgrind: m_libcfile.c:66 (vgPlain_safe_fd): Assertion 'newfd >= VG_(fd_hard_limit)' failed.
Cannot find memory tester output file: /builds/user/boost-multi/build/Testing/Temporary/MemoryChecker.51.log
机器非常相似,都是英特尔i7。我能想到的唯一区别是一个是:
**答:**Ubuntu 22.10,Linux 5.19.0-29,Docker 2016年10月20日
另一个:
**B.**Fedora 37,Linux操作系统6.1.7-200.fc37.x86_64,文档扩充程序20.10.23
也许还有一些我不知道的 Docker 的配置。
是否存在可能产生差异的docker配置?或内核配置?或valgrind中的某个选项来解决此问题?
我知道一个事实,在真实的机器(不是docker)valgrind不会产生任何内存错误。
我为valgrind使用的选项总是-leak-check=yes --num-callers=51 --trace-children=yes --leak-check=full --track-origins=yes --gen-suppressions=all
。图像中的Valgrind版本是来自debian:testing
图像的3.19.0-1
。
注意这不是valgrind报告的错误,这是valgrind内部的错误,也许唯一的区别是Ubuntu版本的valgrind是在发布模式下编译的,错误被忽略了(〈--这没有意义,valgrind在两种情况下是一样的,因为docker映像是一样的)。
我尝试删除--num-callers=51
或将其设置为12(默认值),但无济于事。
2条答案
按热度按时间imzjd6km1#
我发现了图像和真实机器之间的差异和一个解决方案。它与文件描述符的数量有关。(这在Mac OS上的valgind bug问题的一个线程中简要指出https://bugs.kde.org/show_bug.cgi?id=381815#c0)
在Ubuntu 22.10中运行的Docker映像内部:
在Fedora 37中运行的docker映像内部:
(看起来像一个可笑的数字或溢出)
在Fedora 37 * 和 * Ubuntu 22.10 * 真实 * 计算机中:
因此,在CI配方中这样做,"解决"了问题:
我不知道为什么这个变通方案有效。
供参考:
lkaoscv72#
首先,用Valgrind参数表示“你做错了”。对于CI,我建议使用两个阶段的方法。在CI运行中使用尽可能多的默认参数(--trace-children=yes可能是必需的,但其他的不是).如果你的代码库有漏洞,那么你可能需要检查漏洞,但如果你能保持零泄漏政策(或仅抑制泄漏),则可以从摘要中判断是否存在新泄漏。在您的CI检测到问题后,您可以使用厨房Flume选项再次运行以获取完整信息。如果不使用所有这些选项,您的运行速度将显著加快。
回到问题上来。
Valgrind试图dup()某个文件(客户机exe,临时文件或类似的文件),它得到的fd比它认为的nofilerlimit要高,所以它Assert。
十亿个文件太荒谬了。
Valgrind将尝试调用prlimit RLIMIT_NOFILE,并回退调用rlimit,然后再回退一次将限制设置为1024。
要真正了解发生了什么,您需要修改Valgrind源代码(m_main. c,setup_file_descriptor,将本地
show
设置为True)。否则我看斯特拉斯
(all RHEL 7.6修正案64中的上述内容)
编辑:注意上面显示了Valgrind查询和设置资源限制。如果你在运行Valgrind之前使用ulimit来降低限制,那么Valgrind会尝试遵守这个限制。还要注意Valgrind保留了少量(8)文件供自己使用。