.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
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Valgrind-users mailing list
Valgrind-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/valgrind-users

Reply via email to