如何检测程序是否在valgrind中运行?

Tom*_*Tom 9 c++ unit-testing valgrind

有没有办法在运行时识别可执行文件正在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);
}
Run Code Online (Sandbox Code Playgroud)

运行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)
Run Code Online (Sandbox Code Playgroud)

我想修改我的单元测试,以便在从valgrind中运行时简单地跳过有问题的代码.这可能吗?

Has*_*kun 18

您应该从Valgrind手册中查看此页面,它包含一个RUNNING_ON_VALGRIND宏(包含在valgrind.h中),可以满足您的需要.


vin*_*c17 6

如果不想包含valgrind.h(需要 autoconf 测试或类似测试)或使用包装器,这里有一个适用于 Linux(和其他使用 ELF 的系统?)的启发式方法:测试LD_PRELOAD环境变量的值,因为 Valgrind 通过预加载库工作。我在 C 中使用以下测试来检查是否LD_PRELOAD包含字符串"/valgrind/""/vgpreload"

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);
}
Run Code Online (Sandbox Code Playgroud)

其他系统可能有类似的解决方案。建议使用以下命令查看环境是否提到Valgrind:

valgrind env | grep -i valgrind
Run Code Online (Sandbox Code Playgroud)