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 q
usr
- потребление 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.pcap
wireshark
работает на уровне 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.3
Scapy
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 report
1 строчка запускает сбор счетчика 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_sendmsg
perf 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.svg
vmstat
Использование:
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