有没有办法在运行时识别可执行文件是从valgrind中运行的?我有一组C ++单元测试,其中一个期望std::vector::reserve
抛出std::bad_alloc
。当我在valgrind下运行时,它完全挽救,阻止我测试内存泄漏(使用valgrind)和行为(期望抛出异常)。
这是一个重现它的最小例子:
#include <vector>
int main()
{
size_t uint_max = static_cast<size_t>(-1);
std::vector<char> v;
v.reserve(uint_max);
}
运行valgrind,我得到了这个输出:
Warning: silly arg (-1) to __builtin_new()
new/new[] failed and should throw an exception, but Valgrind
cannot throw exceptions and so is aborting instead. Sorry.
at 0x40192BC: VALGRIND_PRINTF_BACKTRACE (valgrind.h:319)
by 0x401C823: operator new(unsigned) (vg_replace_malloc.c:164)
by 0x80487BF: std::vector<char, std::allocator<char> >::reserve(unsigned) new_allocator.h:92)
by 0x804874D: main (vg.cxx:6)
我想修改单元测试,以便在从valgrind中运行时简单地跳过有问题的代码。这可能吗?
答案 0 :(得分:18)
您应该从Valgrind手册中查看this page,它包含一个RUNNING_ON_VALGRIND
宏(包含在valgrind.h中),可以满足您的需求。
答案 1 :(得分:3)
如果不想包含valgrind.h
(需要进行autoconf测试或类似的测试)或不使用包装器,那么这对于Linux(以及其他使用ELF的系统?)是一种启发式方法:测试{{ 1}}环境变量,因为Valgrind通过预加载库来工作。我在C语言中使用以下测试来检查LD_PRELOAD
是否包含字符串LD_PRELOAD
或"/valgrind/"
:
"/vgpreload"
其他系统可能具有类似的解决方案。我建议使用以下命令来查看环境是否提到了Valgrind:
int tests_run_within_valgrind (void)
{
char *p = getenv ("LD_PRELOAD");
if (p == NULL)
return 0;
return (strstr (p, "/valgrind/") != NULL ||
strstr (p, "/vgpreload") != NULL);
}
答案 2 :(得分:0)
我查看了valgrind doucmentation并没有找到一个简单的答案。但是您可以尝试以下几种方法:
围绕有问题的新操作编写自己的包装器,并在valgrind获取其私有新函数之前引发异常。
尝试上面提到的海报,除了使用环境变量代替命令行选项(需要管道):
MYAPP_UNIT_TESTS_DISABLED="NEW_MINUS_ONE,FLY_TO_MOON,DEREF_NULL" valgrind myapp
然后你可以轻松编写一个函数
bool unit_test_enabled(const char *testname);
根据getenv(3)返回的值保护您的单元测试。