Linux debugging tools
strace
Выводит все системные вызовы программы. Пример запуска:
strace ls
Выводит кучу строк следующего вида:
execve("/bin/ls", ["ls"], [/* 93 vars */]) = 0                 
brk(NULL)                               = 0x558f2b6db000                                       
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap(NULL, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f1ce7ad9000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)           
open("/usr/local/cuda/lib64/tls/x86_64/libselinux.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)Разберем первую строку по частям:
execve- системный вызов("/bin/ls", ["ls"], [/* 93 vars */])- аргументы вызова= 0- возвращаемое значение
Флаги
-e- ограничить показываемые системные вызовы, например,strace -e open-f- (follow) - если программа создает подпроцессы, то следить за их системными вызовами тоже. Лучше использовать этот флаг по умолчанию всегда.-p- присоединиться к уже запущенному процессу, указав его PID, например,strace -p 747-s- показывать первые N символов для всех выводимых строк (имена файлов строками не считаются), например,strace -s 800. Дефолтный размер строк - 32, поэтому лучше указывать побольше.-o- перенаправлять вывод в указанный файл, например,strace -o log.txt
Основные системные вызовы
execve- запуск программыopen- открытие файлаwrite- запись в файлsendto- отправка данных по сетиrecvfrom- получение данных по сети- сетевая активность может осуществляться и через 
read/write 
Пример
Смотрим вызовы SSH-сессии:
strace -f -o ssh.txt ssh mybox
Смотрим, какие файлы открывает dropbox (PID, например, 230):
strace -f -p 230 -e open
dstat
Показывает, сколько данных посылается по сети/пишется на диск каждую секунду.
Пример запуска:
dstat
Вывод:
----total-cpu-usage---- -dsk/total- -net/total- ---paging-- ---system--
usr sys idl wai hiq siq| read  writ| recv  send|  in   out | int   csw 
  2   1  96   0   0   0| 165k 1183k|   0     0 |   0     0 |2665  4578 
  6   6  84   4   0   1|   0    12M|  14k 3348B|   0     0 |4468    12k
  3   5  85   5   0   1|   0    12M|8681B 3348B|   0     0 |4156  9436 
  4   3  86   7   0   1|   0  7880k|  14k 9010B|   0     0 |4368  9721 qusr- потребление CPU пользовательскими процессамиsys- потребление CPU системными процессамиidl- количество простаивающих (idle) процессовwai- количество ожидающих (wait) процессовhiq- количество аппаратных прерываний (hard interrupt)siq- количество программных прерываний (soft interrupt)read- количество операций записиread- количество операций чтенияrecv- количество байт, полученных по сетиsend- количество байт, отправленных по сетиin- количество раз, когда данные были скопированы в памятьout- количество раз, когда данные были скопированы из памятиint- количество прерыванийcsw- количество переключений контекста (context switch)
Дополнительные столбцы по процессам и виртуальной памяти появляютя прииспользовании флага --vmstat.
Пример:
dstat --vmstat
Вывод:
---procs--- ------memory-usage----- ---paging-- -dsk/total- ---system-- ----total-cpu-usage----
run blk new| used  buff  cach  free|  in   out | read  writ| int   csw |usr sys idl wai hiq siq
  0 0.0 6.4|8356M 1474M 7517M  707M|   0     0 | 173k 1238k|2677  4626 |  3   1  96   0   0   0
1.0   0  69|8357M 1474M 7519M  703M|   0     0 |4096B 4440k|3888  7102 |  2   2  87   8   0   0
  0 1.0  73|8358M 1474M 7521M  701M|   0     0 |   0  5972k|4442  8457 |  3   2  86   8   0   1
1.0   0  68|8363M 1475M 7522M  694M|   0     0 |  20k 6068k|4032  7931 |  4   3  86   7   0   1Здесь добавились столбцы:
run- количество работающих процессовblk- количество заблокированных процессовnew- количество новых процессовused- количество использованной памятиbuff- количество буфферизированной памятиcach- количество закешированной памятиfree- количество свободной памяти
Флаги
-c- вывод инфы по процессору-d- вывод инфы по диску-n- вывод инфы по сети-g- вывод инфы по пейджингу-y- вывод инфы по системе
По умолчанию, если не указано никаких флагов, dstat запускается с флагами cdngy.
--top-cpu- вывод процесса, использующего больше всех CPU--top-mem- вывод процесса, потребляющего больше всех памяти--output- вывод в csv файл, например,dstat --output out.csv
tcpdump
Позволяет сдампить сетевой трафик в файл, чтобы потом его открыть через wireshark.
Опции запуска
-n- не преобразовывать численные адреса в имена-v/vv/vvv- verbose output-X- помимо заголовков пакетов, печатать так же их тела
Пример:
sudo tcpdump -i wlan 0 \
              src port 80 or dst port 80 \
              -w port-80-recording.pcap`А потом открываем результат wireshark-ом:
wireshark port-80-recording.pcapwireshark работает на уровне tcp и ничего не знает про http. Если нужно работать с HTTP-трафиком, то может помочь tshark, но у меня на дебиане он не запустился.
Правила фильтрации
http://www.tcpdump.org/manpages/pcap-filter.7.html
dst port ya.ru- порт назначения = 80 (работает только с ip/tcp, ip/udp, ip6/tcp, ip6/udp)src port ya.ru- порт источника = 80dst host ya.ru- хост назначения = ya.rusrc host ya.ru- хост источника = ya.ruhost ya.ru- хост назначения или источника = ya.ru
Перед host можно писать ip, arp, rarp, ip6 для указани протокола, например:
ip host ya.ru
proto protocol- пакет является ip4 или ip6 пакетом указанного протокола (tcp, udp, icmp)tcp, udp, icmp- аббревиатура дляproto p, где p - протокол
Wireshark
В wireshark свой язык фильтрации, вот как, например, отфильтровать по ip-адресу источника:
ip.src == 192.168.1.3Для назначения, соответственно:
ip.dst == 192.168.1.3Если нужно в обе стороны, то:
ip.src == 192.168.1.3 or ip.dst == 192.168.1.3либо же воспользоваться алиасом addr:
ip.addr == 192.168.1.3Scapy
Scapy это интерпретатор на основе питона, позволяющий отправлять, перехватывать, декодировать и анализивовать сетевые пакеты.
Отправка пакета:
$ scapy
>>> send(IP(dst="10.0.0.1")/ICMP()/"This is an ICMP packet") Анализ .pcap:
$ scapy
>>> pcap = rdpcap('traffic.pcap')
>>> str = ''.join(str(p.payload.payload.payload) for p in pcap)perf
Поможет ответить на следующие вопросы:
- почему ядро так грузит процессор?
 - какие ветки кода генерят промахи кэша L2?
 - сильно ли чтения памяти тормозят процессор?
 - какие ветки кода выделяют память и сколько?
 - из-за чего происходит переотправка пакетов TCP?
 - вызывается ли определенная функция ядра, и как часто?
 - по какой причине потоки покидают процессор?
 
Установка
sudo apt-get install linux-toolsПример использования
sudo perf record -e block:block_rq_issue -ag
sudo perf report1 строчка запускает сбор счетчика block:block_rq_issue, который отслеживает обращения к диску. Эта команда ничего не выдает на экран, но в фоне собирает и записывает инфу в файл perf.data до тех пор, пока ее не остановим через Ctrl-C.
2 строчка открывает отчет. Окно интерактивное, можно стрелочками выбрать строку и раскрыть ее (Enter). Кнопка E раскрывает все узлы.
Если в стектрейсах вместо названий функций 16-ричные числа - значит, нужно установить символы отладки для этой программы. Часто их можно установить через apt-get, добавив суффикс -dbgsym, например: libc6-dbgsym.
При использовании с джавой или NodeJS нужно, чтобы JIT-компилятор писал символы отладки в файл /tmp/perf-PID.map. Для джавы это делает perf-map-agent, для ноды - флаг --perf_basic_prof. Здесь есть инструкции, как их использовать.
Полезные команды
Трейсить - собирать инфу по каждому ивенту
Сэмплить - собирать инфу по подмножеству ивентов, например один раз на каждые 50 выстрелов
Эти команды выдают результат в терминал
perf stat *command*- статистика процессора при выполнении указанной командыperf stat -d *command*- расширенная статистикаperf stat -p *PID*- статистика процессора для указанного процесса, собирается пока не нажато Ctrl-Cperf stat -a sleep 5- собирать статистику процессора для всей системы в течение 5 секундperf stat -e cycles,instructions,cache-references,cache-misses,bus-cycles -a sleep 10- разные статистики процессора для всей системы в течение 10 секундperf stat -e L1-dcache-loads,L1-dcache-load-misses,L1-dcache-stores *command*- статистики кэша L1 для указанной командыperf stat -e dTLB-loads,dTLB-load-misses,dTLB-prefetch-misses *command*- статистики TLB для указанной командыperf stat -e LLC-loads,LLC-load-misses,LLC-stores,LLC-prefetches **command**- статистики кэша LLC для указанной командыperf stat -e raw_syscalls:sys_enter -I 1000 -a- считать количество сисколлов в секунду для всей системыperf stat -e 'syscalls:sys_enter_*' -p **PID**- считать количество сисколлов и группировать их по типу для указанного процесса, пока не будет нажато Ctrl-Cperf stat -e 'syscalls:sys_enter_*' -a sleep 5- считать количество сисколлов и группировать их по типу для всей системы в течение 5 секундperf record -e sched:sched_process_exec -a- трейсить все новые процессы до Ctrl-Cperf record -e context-switches -a- сэмплить контекст-свитчи до Ctrl-Cperf record -e context-switches -c 1 -a- трейсить все контекст-свитчи до Ctrl-Cperf probe --add tcp_sendmsg- добавить возможность отслеживания вызовов функцииtcp_sendmsgperf probe -d tcp_sendmsg- удалить возможность отслеживания вызовов функцииtcp_sendmsg
Флэйм-графы
git clone https://github.com/brendangregg/FlameGraph  # or download it from github
cd FlameGraph
perf record -F 99 -ag -- sleep 60
perf script | ./stackcollapse-perf.pl > out.perf-folded
cat out.perf-folded | ./flamegraph.pl > perf-kernel.svgvmstat
Использование:
vmstat 2 6С такими аргументами статистика использования виртуальной памяти будет показываться каждые 2 секунды 6 раз. Первая строчка всегда дает средние значения с последней перезагрузки. Последующие дают средние значения за время delay, указывающееся первым числовым аргументом.
Можно выводить статистику по использованию диска: vmstat -d 2 6.
Пример вывода на Debian в режиме VM:
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 1  0 5866632 302212 1028888 4434828    0    1    13    61    2    2  3  2 95  0  0
 0  0 5866632 291460 1028896 4435540    0    0     0   220 9818 17977  4  2 94  0  0
 6  0 5866632 293752 1028896 4435996    0    0     0     0 10499 21794  8  4 88  0  0
 0  0 5866632 290568 1028896 4436376    0    0     0  2328 10009 18690  4  3 93  0  0
 0  0 5866632 289300 1028912 4436496    0    0     0   738 9977 18418  3  3 95  0  0
 0  0 5866632 289728 1028924 4436684    0    0     0   120 10139 19331  3  2 95  0  0Описание полей:
Procs
- r: The number of runnable processes (running or waiting for run time).
 - b: The number of processes in uninterruptible sleep.
 
Memory
- swpd: the amount of virtual memory used.
 - free: the amount of idle memory.
 - buff: the amount of memory used as buffers.
 - cache: the amount of memory used as cache.
 - inact: the amount of inactive memory. (-a option)
 - active: the amount of active memory. (-a option)
 
Swap
- si: Amount of memory swapped in from disk (/s).
 - so: Amount of memory swapped to disk (/s).
 
IO
- bi: Blocks received from a block device (blocks/s).
 - bo: Blocks sent to a block device (blocks/s).
 
System
- in: The number of interrupts per second, including the clock.
 - cs: The number of context switches per second.
 
CPU
These are percentages of total CPU time.
- us: Time spent running non-kernel code. (user time, including nice time)
 - sy: Time spent running kernel code. (system time)
 - id: Time spent idle. Prior to Linux 2.5.41, this includes IO-wait time.
 - wa: Time spent waiting for IO. Prior to Linux 2.5.41, included in idle.
 - st: Time stolen from a virtual machine. Prior to Linux 2.6.11, unknown.
 
Дисковый режим
vmstat -d 1 1Результат:
disk- ------------reads------------ ------------writes----------- -----IO------
       total merged sectors      ms  total merged sectors      ms    cur    sec
sda   4875777 1816309 473984778 5311008 18301794 32203707 2244809614 197933460      0  18362
dm-0  4802238      0 458568874 6456436 43560867      0 2203748144 777588792      0  17997
dm-1  1908554      0 15272184 2384716 5123066      0 40984528 200874876      0   1287
loop0 227474      0  457018   57800      0      0       0       0      0      2
loop1    535      0    3100      76      0      0       0       0      0      0
loop2    538      0    3102      68      0      0       0       0      0      0
loop3     33      0     120       0      0      0       0       0      0      0
loop4      0      0       0       0      0      0       0       0      0      0
loop5      0      0       0       0      0      0       0       0      0      0
loop6      0      0       0       0      0      0       0       0      0      0
loop7      0      0       0       0      0      0       0       0      0      0Описание полей
Reads
- total: Total reads completed successfully
 - merged: grouped reads (resulting in one I/O)
 - sectors: Sectors read successfully
 - ms: milliseconds spent reading
 
Writes
- total: Total writes completed successfully
 - merged: grouped writes (resulting in one I/O)
 - sectors: Sectors written successfully
 - ms: milliseconds spent writing
 
IO
- cur: I/O in progress
 - s: seconds spent for I/O