From: Benjamin M. <ben...@gm...> - 2017-10-09 17:38:18
|
.Hi All, I am using Google Test's EXPECT_EXIT() to sandbox my code in a separate process on my x86_64 Ubuntu machine and I'm trying to check if there are any memory leaks in my code. To verify that memory leaks can be detected I created a dummy test below: void leaky_function(void) { int* sub_proc_leak = (int*) malloc(1000); } TEST(my_test_case, memory_leak) { EXPECT_EXIT({ leaky_function(); exit(0); }, ::testing::ExitedWithCode(0),""); } I'm compiling it using cmake/make to link in google test with the binary being called mem_leak_test. I'm then running it with: $ valgrind -v --trace-children=yes --tool=memcheck --leak-check=full --show-leak-kinds=all ./mem_leak_test I would expect that it would detect 2000 bytes lost, or somehow indicate that 1000 bytes were lost in the subprocess launched by EXPECT_EXIT() and another in the main process. However, the LEAK summary only indicates 1000 bytes lost total: ==64382== LEAK SUMMARY: ==64382== definitely lost: 1,000 bytes in 1 blocks ==64382== indirectly lost: 0 bytes in 0 blocks ==64382== possibly lost: 0 bytes in 0 blocks ==64382== still reachable: 72,704 bytes in 1 blocks ==64382== suppressed: 0 bytes in 0 blocks and if I comment out the second call to leaky_function() it will indicate 0 bytes lost. Is there a way to run my test with valgrind such that it detects the memory leak in the subprocess? According to valgrind's documentation: --trace-children=<yes|no> [default: no] When enabled, Valgrind will trace into sub-processes initiated via the exec system call. This is necessary for multi-process programs. Note that Valgrind does trace into the child of a fork (it would be difficult not to, since fork makes an identical copy of a process), so this option is arguably badly named. However, most children of fork calls immediately call exec anyway. With this in mind I looked into how Google Test implements their EXPECT_EXIT() macro and found that it uses clone() by default, but it has a flag that can be toggled so that it uses fork() & execve() instead. So I toggled that to true as shown below: GTEST_DEFINE_bool_( death_test_use_fork, internal::BoolFromGTestEnv("death_test_use_fork", true), "Instructs to use fork()/_exit() instead of clone() in death tests. " "Ignored and always uses fork() on POSIX systems where clone() is not " "implemented. Useful when running under valgrind or similar tools if " "those do not support clone(). Valgrind 3.3.1 will just fail if " "it sees an unsupported combination of clone() flags. " "It is not recommended to use this flag w/o valgrind though it will " "work in 99% of the cases. Once valgrind is fixed, this flag will " "most likely be removed."); As far as I can tell, Valgrind's documentation says that it can detect memory leaks in a fork()/exec() subprocess and I have confirmed that my google test is in fact calling execve() under the covers of the EXPECT_EXIT(). Is this the correct interpretation of Valgrind's documentation? And if so, why is it that Valgrind does not report the memory leak in the subprocess? Thanks, ~Benjamin |