Отладка и профилирование в Linux
Отладка и профилирование
gdb
No comments. Документацию смотреть здесь.
diff
Применяется, если после добавления нового функционала программа перестала работать. :-)
Использую: diff, git diff, gitk, git bisect -- поиск изменений в коммитах git, приведших к ошибке, и очень удобный diff+merge -- meld.
valgrind
Поиск утечек памяти и профилирование. Описание и перечень вспомогательных инструментов смотреть здесь.
Недостатки:
No comments. Документацию смотреть здесь.
diff
Применяется, если после добавления нового функционала программа перестала работать. :-)
Использую: diff, git diff, gitk, git bisect -- поиск изменений в коммитах git, приведших к ошибке, и очень удобный diff+merge -- meld.
valgrind
Поиск утечек памяти и профилирование. Описание и перечень вспомогательных инструментов смотреть здесь.
Недостатки:
- низкая производительность и высокая нагрузка системы;
- не умеет обнаруживать граничные ошибки при использовании статических или помещенных в стек данных;
- обнаруживает утечки там, где их нет, например, при использовании собственных аллокаторов, разделяемой памяти и проч.
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
#!/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
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.