Valgrind Valgrind
Что такое valgrind? Valgrind – это набор инструментов, для валидации и профилирования. Valgrind доступен  только  для Linux и  некоторых UNIX (например, для Mac OS X).
Какие инструменты входят в valgrind? Валидаторы: Memcheck
Ptrcheck (эксперементальный)
Data Race Detector (DRD)
Helgrind Инструменты профилирования: Lackey
Cachegrind
Callgrind
Massif
Memcheck Предназначен для обнаружения ошибок работы с кучей в C  и С++ Может обнаружить обращения к  высвобожденной области памяти, обращения за пределы выделенной  области памяти или memory leak.
Как работает Memcheck? При выделении нового куска памяти: Области, которые выделяет valgrind для отслеживания  выхода за границу То, что мы выделяем
Как работает Memcheck? При высвобождении куска памяти: То, что мы выделили, и хотим высвободить Становится  недоступным, но не высвобождается.
Как  работает  Memcheck? Он также контролирует доступ к  неинициализированным переменным на стеке, или в статической памяти int main() { int x; printf ("x = %d\n", x); } Conditional jump or move depends on uninitialised value(s) at 0x402DFA94: _IO_vfprintf (_itoa.h:49) by 0x402E8476: _IO_printf (printf.c:36) by 0x8048472: main (tests/test.cpp:10)
Проблемы Memcheck Из-за ограниченности ресурсов нельзя долго держать большие куски памяти Нельзя выделять большие куски памяти для отслеживания выхода за границы Нет механизма отслеживания ошибок  работы со стеком или статической  памятью
Ptrcheck Предназначен для обнаружения ошибок работы с кучей, стеком и статической памятью в C  и С++ Это экспериментальный инструмент,  который должен определять часть  ошибок, которые не определяет  Memcheck
Data Race Detector (DRD) Может быть использован, только с программой, которая построена на POSIX thread API Предназначен для обнаружения ошибок, характерных для многопоточных  программ:  отсутствие синхронизации там, где она нужна
длительные блокировок на объектах синхронизации
неправильное использование POSIX thread API
DRD – отсутствие синхронизации $ valgrind --tool=drd --read-var-info=yes drd/tests/rwlock_race ... ==9466== Thread 3: ==9466== Conflicting load by thread 3 at 0x006020b8 size 4 ==9466==  at 0x400B6C: thread_func (rwlock_race.c:29) ==9466==  by 0x4C291DF: vg_thread_wrapper (drd_pthread_intercepts.c:186) ==9466==  by 0x4E3403F: start_thread (in /lib64/libpthread-2.8.so) ==9466==  by 0x53250CC: clone (in /lib64/libc-2.8.so) ==9466== Location 0x6020b8 is 0 bytes inside local var "s_racy" ==9466== declared at rwlock_race.c:18, in frame #0 of thread 3 ==9466== Other segment start (thread 2) ==9466==  at 0x4C2847D: pthread_rwlock_rdlock* (drd_pthread_intercepts.c:813) ==9466==  by 0x400B6B: thread_func (rwlock_race.c:28) ==9466==  by 0x4C291DF: vg_thread_wrapper (drd_pthread_intercepts.c:186) ==9466==  by 0x4E3403F: start_thread (in /lib64/libpthread-2.8.so) ==9466==  by 0x53250CC: clone (in /lib64/libc-2.8.so) ==9466== Other segment end (thread 2) ==9466==  at 0x4C28B54: pthread_rwlock_unlock* (drd_pthread_intercepts.c:912) ==9466==  by 0x400B84: thread_func (rwlock_race.c:30) ==9466==  by 0x4C291DF: vg_thread_wrapper (drd_pthread_intercepts.c:186) ==9466==  by 0x4E3403F: start_thread (in /lib64/libpthread-2.8.so) ==9466==  by 0x53250CC: clone (in /lib64/libc-2.8.so)

Valgrind

  • 1.
  • 2.
    Что такое valgrind?Valgrind – это набор инструментов, для валидации и профилирования. Valgrind доступен только для Linux и некоторых UNIX (например, для Mac OS X).
  • 3.
    Какие инструменты входятв valgrind? Валидаторы: Memcheck
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
    Memcheck Предназначен дляобнаружения ошибок работы с кучей в C и С++ Может обнаружить обращения к высвобожденной области памяти, обращения за пределы выделенной области памяти или memory leak.
  • 11.
    Как работает Memcheck?При выделении нового куска памяти: Области, которые выделяет valgrind для отслеживания выхода за границу То, что мы выделяем
  • 12.
    Как работает Memcheck?При высвобождении куска памяти: То, что мы выделили, и хотим высвободить Становится недоступным, но не высвобождается.
  • 13.
    Как работает Memcheck? Он также контролирует доступ к неинициализированным переменным на стеке, или в статической памяти int main() { int x; printf ("x = %d\n", x); } Conditional jump or move depends on uninitialised value(s) at 0x402DFA94: _IO_vfprintf (_itoa.h:49) by 0x402E8476: _IO_printf (printf.c:36) by 0x8048472: main (tests/test.cpp:10)
  • 14.
    Проблемы Memcheck Из-заограниченности ресурсов нельзя долго держать большие куски памяти Нельзя выделять большие куски памяти для отслеживания выхода за границы Нет механизма отслеживания ошибок работы со стеком или статической памятью
  • 15.
    Ptrcheck Предназначен дляобнаружения ошибок работы с кучей, стеком и статической памятью в C и С++ Это экспериментальный инструмент, который должен определять часть ошибок, которые не определяет Memcheck
  • 16.
    Data Race Detector(DRD) Может быть использован, только с программой, которая построена на POSIX thread API Предназначен для обнаружения ошибок, характерных для многопоточных программ: отсутствие синхронизации там, где она нужна
  • 17.
    длительные блокировок наобъектах синхронизации
  • 18.
  • 19.
    DRD – отсутствиесинхронизации $ valgrind --tool=drd --read-var-info=yes drd/tests/rwlock_race ... ==9466== Thread 3: ==9466== Conflicting load by thread 3 at 0x006020b8 size 4 ==9466== at 0x400B6C: thread_func (rwlock_race.c:29) ==9466== by 0x4C291DF: vg_thread_wrapper (drd_pthread_intercepts.c:186) ==9466== by 0x4E3403F: start_thread (in /lib64/libpthread-2.8.so) ==9466== by 0x53250CC: clone (in /lib64/libc-2.8.so) ==9466== Location 0x6020b8 is 0 bytes inside local var "s_racy" ==9466== declared at rwlock_race.c:18, in frame #0 of thread 3 ==9466== Other segment start (thread 2) ==9466== at 0x4C2847D: pthread_rwlock_rdlock* (drd_pthread_intercepts.c:813) ==9466== by 0x400B6B: thread_func (rwlock_race.c:28) ==9466== by 0x4C291DF: vg_thread_wrapper (drd_pthread_intercepts.c:186) ==9466== by 0x4E3403F: start_thread (in /lib64/libpthread-2.8.so) ==9466== by 0x53250CC: clone (in /lib64/libc-2.8.so) ==9466== Other segment end (thread 2) ==9466== at 0x4C28B54: pthread_rwlock_unlock* (drd_pthread_intercepts.c:912) ==9466== by 0x400B84: thread_func (rwlock_race.c:30) ==9466== by 0x4C291DF: vg_thread_wrapper (drd_pthread_intercepts.c:186) ==9466== by 0x4E3403F: start_thread (in /lib64/libpthread-2.8.so) ==9466== by 0x53250CC: clone (in /lib64/libc-2.8.so)
  • 20.
    DRD – длительнаяблокировка Программа hold_lock блокирует mutex на заданное количество милисекунд: ... hold_lock.c:51 pthread_mutex_lock( &mutex ); hold_lock.c:52 hold_lock.c:53 usleep( interval * 1000 ); hold_lock.c:54 hold_lock.c:55 pthread_mutex_unlock( &mutex ); ... $ valgrind --tool=drd --exclusive-threshold=10 drd/tests/hold_lock -i 500 ... ==10668== Acquired at: ==10668== at 0x4C267C8: pthread_mutex_lock (drd_pthread_intercepts.c:395) ==10668== by 0x400D92: main (hold_lock.c:51) ==10668== Lock on mutex 0x7fefffd50 was held during 503 ms (threshold: 10 ms). ==10668== at 0x4C26ADA: pthread_mutex_unlock (drd_pthread_intercepts.c:441) ==10668== by 0x400DB5: main (hold_lock.c:55) ... $ valgrind --tool=drd --exclusive-threshold=10 drd/tests/hold_lock -i 500 ... ==10668== Acquired at: ==10668== at 0x4C267C8: pthread_mutex_lock (drd_pthread_intercepts.c:395) ==10668== by 0x400D92: main (hold_lock.c:51) ==10668== Lock on mutex 0x7fefffd50 was held during 503 ms (threshold: 10 ms). ==10668== at 0x4C26ADA: pthread_mutex_unlock (drd_pthread_intercepts.c:441) ==10668== by 0x400DB5: main (hold_lock.c:55) ...
  • 21.
    Helgrind Может бытьиспользован, только с программой, которая построена на POSIX thread API Предназначен для обнаружения ошибок, характерных для многопоточных программ: отсутствие синхронизации там, где она нужна
  • 22.
    дедлоки из-за неправильногопорядка захвата объектов синхронизации
  • 23.
  • 24.
    Helgrind – отсутствиесинхронизации simple_race.c:3 int var = 0; simple_race.c:4 simple_race.c:5 void* child_fn ( void* arg ) { simple_race.c:6 var++; /* Unprotected relative to parent */ simple_race.c:7 return NULL; simple_race.c:8 } simple_race.c:9 simple_race.c:10 int main ( void ) { simple_race.c:11 pthread_t child; simple_race.c:12 pthread_create(&child, NULL, child_fn, NULL); simple_race.c:13 var++; /* Unprotected relative to child */ simple_race.c:14 pthread_join(child, NULL); simple_race.c:15 return 0; simple_race.c:16 } Possible data race during read of size 4 at 0x601038 by thread #1 at 0x400606: main (simple_race.c:13) This conflicts with a previous write of size 4 by thread #2 at 0x4005DC: child_fn (simple_race.c:6) by 0x4C29AFF: mythread_wrapper (hg_intercepts.c:194) by 0x4E3403F: start_thread (in /lib64/libpthread-2.8.so) by 0x511C0CC: clone (in /lib64/libc-2.8.so) Location 0x601038 is 0 bytes inside global var "var" declared at simple_race.c:3
  • 25.
    Helgrind – deadlocksHelgrind также сообщает ''правильный'' порядок захвата, но только для случая с двумя объектами синхронизации. Helgrind отслеживает порядок захвата объектов синхронизации. Если два или более объектов синхронизации могут быть захвачены в пределах одного потока в разном порядке – Hellgrind сообщает о проблеме.
  • 26.
    Helgrind – deadlocksСообщение о нарушении порядка захвата объектов синхронизации для двух mutex'ов выглядит следующим образом: Thread #1: lock order "0x7FEFFFAB0 before 0x7FEFFFA80" violated at 0x4C23C91: pthread_mutex_lock (hg_intercepts.c:388) by 0x40081F: main (tc13_laog1.c:24) Required order was established by acquisition of lock at 0x7FEFFFAB0 at 0x4C23C91: pthread_mutex_lock (hg_intercepts.c:388) by 0x400748: main (tc13_laog1.c:17) followed by a later acquisition of lock at 0x7FEFFFA80 at 0x4C23C91: pthread_mutex_lock (hg_intercepts.c:388) by 0x400773: main (tc13_laog1.c:18)
  • 27.
    Как всем этимпользоваться? Valgrind позволяет анализировать только код на ассемблере, C, C++ и FORTRAN. Для начала анализа надо запустить Valgrind с параметром --tool=<инструмент> Например: $> valgrind --tool=hellgrind ./my_app my_param
  • 28.
    Где можно узнатьбольше? http://valgrind.org
  • 29.