munit icon indicating copy to clipboard operation
munit copied to clipboard

Valgrind report 'still reachable' warning on test_name

Open perror opened this issue 5 years ago • 2 comments

I have strange behavior with valgrind. Basically, I defined my test suite as follow:

  /* Set the test cases */
  MunitTest test_cases[] =
    {
     { "trace/instr", test_instr, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL },
     { "trace/hash", test_hash, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL },
     { "trace/hashtable", test_hashtable, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL },
     { NULL, NULL, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL },
    };

  /* Set the test suite */
  const MunitSuite test_suite[] =
    {
     { "libafl/", test_cases, NULL, 1, MUNIT_SUITE_OPTION_NONE },
     { NULL, NULL, NULL, 0, MUNIT_SUITE_OPTION_NONE }
    };

But, the problem is that valgrind detect a "still reachable" memory area in each process. For example the last test gives:

[ OK    ] [ 0.00903018 / 0.00862850 CPU ]
libafl/trace/hashtable               ==8031== 
==8031== HEAP SUMMARY:
==8031==     in use at exit: 23 bytes in 1 blocks
==8031==   total heap usage: 21 allocs, 20 frees, 5,050 bytes allocated
==8031== 
==8031== 23 bytes in 1 blocks are still reachable in loss record 1 of 1
==8031==    at 0x483577F: malloc (vg_replace_malloc.c:299)
==8031==    by 0x4848C03: munit_maybe_concat (munit.c:1110)
==8031==    by 0x484A7D8: munit_test_runner_run_test (munit.c:1556)
==8031==    by 0x484B028: munit_test_runner_run_suite (munit.c:1677)
==8031==    by 0x484B1A0: munit_test_runner_run (munit.c:1696)
==8031==    by 0x484CAA5: munit_suite_main_custom (munit.c:2026)
==8031==    by 0x484CCCA: munit_suite_main (munit.c:2054)
==8031==    by 0x10BD45: main (test_trace.c:189)
==8031== 
==8031== LEAK SUMMARY:
==8031==    definitely lost: 0 bytes in 0 blocks
==8031==    indirectly lost: 0 bytes in 0 blocks
==8031==      possibly lost: 0 bytes in 0 blocks
==8031==    still reachable: 23 bytes in 1 blocks
==8031==         suppressed: 0 bytes in 0 blocks
==8031== 
==8031== For counts of detected and suppressed errors, rerun with: -v
==8031== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
[ OK    ] [ 0.01238986 / 0.01177837 CPU ]
3 of 3 (100%) tests successful, 0 (0%) test skipped.
==8028== 
==8028== HEAP SUMMARY:
==8028==     in use at exit: 0 bytes in 0 blocks
==8028==   total heap usage: 12 allocs, 12 frees, 4,612 bytes allocated
==8028== 
==8028== All heap blocks were freed -- no leaks are possible
==8028== 
==8028== For counts of detected and suppressed errors, rerun with: -v
==8028== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

Note that the size of the "still reachable" memory area is exactly the size of the string enclosing the name of the test (plus the \0 character at the end).

One way to make the error vanish seems to simply declare the test suite as follow:

 /* Set the test cases */
  MunitTest test_cases[] =
    {
     { "libafl/trace/instr", test_instr, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL },
     { "libafl/trace/hash", test_hash, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL },
     { "libafl/trace/hashtable", test_hashtable, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL },
     { NULL, NULL, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL },
    };

  /* Set the test suite */
  const MunitSuite test_suite[] =
    {
     { "", test_cases, NULL, 1, MUNIT_SUITE_OPTION_NONE },
     { NULL, NULL, NULL, 0, MUNIT_SUITE_OPTION_NONE }
    };

The root name of the test suite is empty and this time valgrind gives a clean report for each test:

All heap blocks were freed -- no leaks are possible

I tried to see what was the problem but couldn't find a good way to solve it (everything seems to be linked to the munit_maybe_free_concat(() function).

perror avatar May 28 '19 14:05 perror