|
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
|
|
From: John R. <jr...@bi...> - 2017-10-09 19:53:36
|
On 10/09/2017 10:38 AM, Benjamin Morgan wrote:
> 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),"");
> }
>
There is only one call to leaky_function() in the above code.
> 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
> and if I comment out the second call to leaky_function() it will indicate 0 bytes lost.
Please show the exact code after commenting out the second call. (The original post has no second call.)
--
|
|
From: Benjamin M. <bmo...@uw...> - 2017-10-09 20:01:10
|
Uh oh, this is embarrassing, but apparently I failed to read the output
correctly. I used the "--log-file=valgrind_mem_leak_%p" to separate the
parent and child process logs by PID, and IT WAS detecting the leak in the
subprocess. (This is an awesome feature btw!!!)I was just missed it before
because I didn't pay enough attention to the PIDs in the logs. Also, the
final leak summary doesn't aggregate the leaked subprocess memory with the
parent process' leaked memory so I thought it wasn't detecting it. Sorry
for spamming the list =/
TL;DR: It is actually doing what I expect, I just failed to read the
results properly.
Sorry again,
~Benjamin
On Mon, Oct 9, 2017 at 12:53 PM, John Reiser <jr...@bi...> wrote:
> On 10/09/2017 10:38 AM, Benjamin Morgan wrote:
>
> 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),"");
>> }
>>
>>
> There is only one call to leaky_function() in the above code.
>
> 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
>>
>
> and if I comment out the second call to leaky_function() it will indicate
>> 0 bytes lost.
>>
>
> Please show the exact code after commenting out the second call. (The
> original post has no second call.)
>
> --
>
> ------------------------------------------------------------
> ------------------
> 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
> Val...@li...
> https://lists.sourceforge.net/lists/listinfo/valgrind-users
>
--
Benjamin Morgan
University of Washington
Electrical Engineering
bmo...@uw...
425.652.9094
|