Image

Imagecpplang 😦busy

Отладка и профилирование в Linux







Отладка и профилирование

gdb
  
No comments. Документацию смотреть здесь.

diff
  Применяется, если после добавления нового функционала программа перестала работать. :-)
  Использую:
diffgit diffgitk, git bisect -- поиск изменений в коммитах git, приведших к ошибке, и очень удобный diff+merge -- meld.

valgrind
  Поиск утечек памяти и профилирование. Описание и перечень вспомогательных инструментов смотреть здесь.
  Недостатки:
  • низкая производительность и высокая нагрузка системы;
  • не умеет обнаруживать граничные ошибки при использовании статических или помещенных в стек данных;
  • обнаруживает утечки там, где их нет, например, при использовании собственных аллокаторов, разделяемой памяти и проч.
  Варианты сценариев использования vallgrind:
memcheck
#!/bin/sh
if [ ! -f `which valgrind` ]; then
exit 0
fi
CMD=$1;
OUTPUT_FILE=$2;
LOG_FILE=$3;
if [[ -z $CMD ]]; then
exit 0
fi
if [[ -z $OUTPUT_FILE ]]; then
OUTPUT_FILE="output.vlg.log";
fi
if [[ -z $LOG_FILE ]]; then
LOG_FILE="valgrind.log";
fi
valgrind --leak-check=full --leak-resolution=high --show-reachable=yes --error-limit=no --undef-value-errors=yes --log-file=$OUTPUT_FILE $CMD > $LOG_FILE 2>&1

callgrind
#!/bin/sh
if [ ! -f `which valgrind` ]; then
exit 0
fi
CMD=$1;
LOG_FILE=$2;
if [[ -z $CMD ]]; then
exit 0
fi
if [[ -z $LOG_FILE ]]; then
LOG_FILE="callgrind.log";
fi
valgrind --dump-instr=yes --trace-jump=yes --tool=callgrind $CMD > $LOG_FILE 2>&1

cachegrind
#!/bin/sh
if [ ! -f `which valgrind` ]; then
exit 0
fi
CMD=$1;
LOG_FILE=$2;
if [[ -z $CMD ]]; then
exit 0
fi
if [[ -z $LOG_FILE ]]; then
LOG_FILE="cachegrind.log";
fi
valgrind --trace-children=yes --tool=cachegrind $CMD > $LOG_FILE 2>&1

strace
  
Трассировщик сигналов и системных вызовов. Подробности в man.

opreport
  
Утилиты oprofile замечательны тем, что не нагружают систему, но предоставляют детальную информацию о производительности. Типичный сценарий использования:
  • запуск программу(ы), которую необходимо исследовать, например, /usr/local/bin/myprogram
  • opcontrol --reset
  • opcontrol --start
  • работаем с программой
  • opcontrol --shutdown
  • opreport -l /usr/local/bin/myprogram > opreport.log
  • opannotate -s /usr/local/bin/myprogram > opannotate.log
В файле opreport.log содержится суммарный отчёт о производительности:
  CPU: Core 2, speed 2999.94 MHz (estimated)
  Counted CPU_CLK_UNHALTED events (Clock cycles when not halted) with a unit mask of 0x00 (Unhalted core cycles) count 100000
  samples % symbol name
  103685988 81.3903 fillBitset
  5387691 4.2292 rb_traverse
  4259675 3.3437 fnv_64_buf
  3396370 2.6660 rbbCompare
  ...

В файле opannotate.log результаты профилирования совмещены с исходным кодом программы:
                              :unsigned fillBitset(userid* uid_, char* bit_set_, unsigned long bit_size_,
     125317 0.0984 : const unsigned hash_k, unsigned long (*p_hash_f)(void *buf, size_t len, unsigned long hval)) { /* fillBitset total: 103685988 81.3903 */
                               :   unsigned long hash;
                               :   unsigned long bitmask;
                               :   unsigned long bitslot;
                               :   int collision = 1;
                               :   unsigned i = 0;
      170787 0.1341 :   for (i = 0; i < HASH_K; ++i) {
      204682 0.1607 :     hash = (*p_hash_f)(uid_, sizeof(userid), i);
      166681 0.1308 :     hash %= bit_size_;
100690305 79.0388 : bitmask = 1 << (hash % CHAR_BIT);
                               :     bitslot = hash / CHAR_BIT;
      621996 0.4882 :      if (!(bit_set_[bitslot] & bitmask)) {
                               :       collision = 0;
    1570526 1.2328 :       bit_set_[bitslot] |= bitmask;
                               :      }
                               :   }
                               :   if (collision) { /* this uid has been found */
                               :     return 0;
                               :   }
                               :   return 1; /* new uid has been registered */
      135694 0.1065 :}

Замечание: в случае, если приложение не было собрано с флагом O0, opannotate может путаться в показаниях и неверно сопоставлять данные профилирования строкам исходного кода.

systemtap
  
Опытные бойцы говорят, что systemtap -- это мощнейшая штука, когда знаешь, что искать.

Всякая вспомогательная мелочёвка
iostat
  
отображает информацию об использовании ЦП и статистику по ВВ/ВЫВ дисков, смотри man.
  Пример использования: iostat -x 1.
  Похожие команды: mpstat, pidstat.

netstat
  Отображает сетевые подключения, смотри man.
  Пример просмотра суммарной статистики для UDP:
  $netstat -su
      
IcmpMsg:
      InType0: 44
      InType3: 2273845
      InType8: 53372
      InType11: 2
      OutType0: 53372
      OutType3: 2273801
      OutType8: 52
  Udp:
      15673636 packets received
      2273731 packets to unknown port received.
      6804686 packet receive errors
      21548911 packets sent
IpExt:
    OutMcastPkts: 34
    InBcastPkts: 479520
    OutBcastPkts: 3008

ps
  Отображает снапшот текущих процессов, смотри man.

top
  Отображает задачи в Linux, смотри man.