簡體   English   中英

如何檢測程序是否在 valgrind 中運行?

[英]How can I detect if a program is running from within 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);
}

運行 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 中運行時簡單地跳過有問題的代碼。 這可能嗎?

您應該從 Valgrind 手冊中查看此頁面,它包含一個RUNNING_ON_VALGRIND宏(包含在 valgrind.h 中),可以執行您想要的操作。

如果不想包含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);
}

其他系統可能有類似的解決方案。 我建議使用以下命令查看環境是否提到Valgrind:

valgrind env | grep -i valgrind

我查看了 valgrind 文檔並沒有找到簡單的答案。 但您可以嘗試以下幾件事:

  • 圍繞有問題的新操作編寫自己的包裝器,並在 valgrind 獲取其私有新函數之前引發異常。

  • 嘗試按照上面建議的海報進行嘗試,除了使用環境變量而不是命令行選項(需要管道):

     MYAPP_UNIT_TESTS_DISABLED="NEW_MINUS_ONE,FLY_TO_MOON,DEREF_NULL" valgrind myapp

然后就可以輕松寫出函數了

bool unit_test_enabled(const char *testname);

根據 getenv(3) 返回的值保護您的單元測試。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM