views:

532

answers:

2

Is there a way to identify at run-time of an executable is being run from within valgrind? I have a set of C++ unit tests, and one of them expects std::vector::reserve to throw std::bad_alloc. When I run this under valgrind, it bails out completely, preventing me from testing for both memory leaks (using valgrind) and behavior (expecting the exception to be thrown).

Here's a minimal example that reproduces it:

#include <vector>
int main()
{
    size_t uint_max = static_cast<size_t>(-1);
    std::vector<char> v;
    v.reserve(uint_max);
}

Running valgrind, I get this output:

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)

I'd like to modify my unit test to simply skip the offending code when it's being run from within valgrind. Is this possible?

A: 

I looked at the valgrind doucmentation and didn't find an easy answer. But here are a couple of things you can try:

  • Write your own wrapper around the offending new operation and raise the exception before valgrind gets its private new function going.

  • Try as poster above suggested except that instead of a command-line option (which requires plumbing) use an environment variable:

    MYAPP_UNIT_TESTS_DISABLED="NEW_MINUS_ONE,FLY_TO_MOON,DEREF_NULL" valgrind myapp
    

Then you can easily write a function

bool unit_test_enabled(const char *testname);

to protect your unit test based on the value returned by getenv(3).

Norman Ramsey
+7  A: 

You should look at this page from the Valgrind manual, it contains a RUNNING_ON_VALGRIND macro (included from valgrind.h) which does what you want.

Hasturkun
Thanks for this, I've been using *grind for years but hardly touched the interface. Its easy to make sanity to include that macro in autoconf .. which automatically turns on my debug printfs() and assertions when running under valrgind if valgrind/valgrind.h is present :)Thanks again! Very helpful
Tim Post