2008-12-13 17 views
5

Czy istnieje sposób identyfikacji w czasie wykonywania pliku wykonywalnego uruchamianego z poziomu valgrind? Mam zestaw testów jednostkowych C++, a jeden z nich oczekuje, że std::vector::reserve rzuci std::bad_alloc. Kiedy uruchamiam to pod wartością valgrind, całkowicie się wycofuje, uniemożliwiając mi przetestowanie obu wycieków pamięci (przy użyciu valgrind) i zachowania (spodziewając się, że wyjątek zostanie odrzucony).Jak mogę sprawdzić, czy program jest uruchomiony z Valgrind?

Oto minimalny przykład, który odtwarza go:

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

Running valgrind, otrzymuję ten wynik:

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) 

Chciałbym zmodyfikować mój testów jednostkowych po prostu pomiń kod naruszające gdy jest jest uruchamiany z Valgrind. czy to możliwe?

Odpowiedz

16

Powinieneś spojrzeć na this page z podręcznika Valgrind, zawiera on makro RUNNING_ON_VALGRIND (zawarte w valgrind.h), które robi to, co chcesz.

+0

Dzięki temu używam * grinda od lat, ale prawie nie dotykałem interfejsu. Łatwo jest zrobić rozsądek, aby włączyć to makro do autoconf .., które automatycznie włącza mój debug printfs() i asercje, gdy działa pod valrgind, jeśli valgrind/valgrind.h jest obecny :) Jeszcze raz dziękuję! Bardzo pomocne –

0

Spojrzałem na douglomerację valgrind i nie znalazłem łatwej odpowiedzi. Ale tutaj jest kilka rzeczy, które można spróbować:

  • Napisz własną owijkę wokół naruszającego nowej pracy i podnieść wyjątek przed valgrind dostaje jej prywatny nowa funkcja dzieje.

  • Spróbuj jak plakat powyżej sugerują, że zamiast opcji wiersza poleceń (co wymaga kanalizacja) użyć zmiennej środowiskowej:

    MYAPP_UNIT_TESTS_DISABLED="NEW_MINUS_ONE,FLY_TO_MOON,DEREF_NULL" valgrind myapp 
    

Następnie można łatwo napisać funkcję

bool unit_test_enabled(const char *testname); 

w celu ochrony testu jednostki na podstawie wartości zwróconej przez getenv (3).

Powiązane problemy