Tracing/USDT: различия между версиями
Vt (обсуждение | вклад) |
Vt (обсуждение | вклад) м (→Использование: форматирование) |
||
Строка 27: | Строка 27: | ||
Есть три варианта использования этих трейспоинтов -- через eBPF, perf_event и ftrace -- все они потребуют рутовых привилегий и трассировка (по умолчанию) происходит для всей системы вцелом (или для указанного процесса). | Есть три варианта использования этих трейспоинтов -- через eBPF, perf_event и ftrace -- все они потребуют рутовых привилегий и трассировка (по умолчанию) происходит для всей системы вцелом (или для указанного процесса). | ||
Использование через ''eBPF'' | === Использование через ''eBPF'' === | ||
==== bcc-tools ==== | |||
В пакете <code>bcc-tools</code> предоставляются следующие утилиты: | |||
* <code>tplist</code> покажет список трейспоинтов: | |||
# tplist -l /usr/lib64/libtcl8.6.so | grep entry | # tplist -l /usr/lib64/libtcl8.6.so | grep entry | ||
/usr/lib64/libtcl8.6.so tcl:cmd__entry | /usr/lib64/libtcl8.6.so tcl:cmd__entry | ||
/usr/lib64/libtcl8.6.so tcl:proc__entry | /usr/lib64/libtcl8.6.so tcl:proc__entry | ||
* <code>bcc trace</code> трассировщик. Пример использования: | |||
шелл-А# bcc trace 'u:/usr/lib64/libtcl8.6.so:cmd__entry "%s", arg1' | шелл-А# bcc trace 'u:/usr/lib64/libtcl8.6.so:cmd__entry "%s", arg1' | ||
PID TID COMM FUNC - | PID TID COMM FUNC - | ||
Строка 41: | Строка 42: | ||
23036 23036 tclsh cmd__entry b'puts' | 23036 23036 tclsh cmd__entry b'puts' | ||
==== bpftrace ==== | |||
В пакете <code>bpftrace</code> одноименная утилита ([https://github.com/iovisor/bpftrace/blob/master/docs/reference%20guide.md документация на англ.]). Пример использования: | |||
шелл-А# bpftrace -e 'usdt:/usr/lib64/libtcl8.6.so:cmd__entry { printf("%s\n", str(arg0)); }' | шелл-А# bpftrace -e 'usdt:/usr/lib64/libtcl8.6.so:cmd__entry { printf("%s\n", str(arg0)); }' | ||
Строка 50: | Строка 52: | ||
puts | puts | ||
Использование через интерфейс ''perf_event'' | === Использование через интерфейс ''perf_event'' === | ||
==== perf ==== | |||
В пакете <code>perf</code> одноименная утилита, пример: | |||
# perf buildid-cache --add /usr/lib64/libtcl8.6.so | # perf buildid-cache --add /usr/lib64/libtcl8.6.so | ||
# perf list | grep sdt_ | grep proc__entry | # perf list | grep sdt_ | grep proc__entry | ||
Строка 65: | Строка 68: | ||
tclsh 22814 [015] 686801.201230: sdt_tcl:proc__entry: (7f9950fdf04e) arg1=94274876797648 arg2=0 arg3=94274876480632 | tclsh 22814 [015] 686801.201230: sdt_tcl:proc__entry: (7f9950fdf04e) arg1=94274876797648 arg2=0 arg3=94274876480632 | ||
Использование через интерфейс ''ftrace'' | === Использование через интерфейс ''ftrace'' === | ||
==== trace-cmd ==== | |||
В пакете <code>trace-cmd</code> одноименная утилита. NB: Сначала необходимо зарегистрировать probe в ядре так же как для <code>perf</code> и только потом использовать. | |||
# perf buildid-cache --add /usr/lib64/libtcl8.6.so | # perf buildid-cache --add /usr/lib64/libtcl8.6.so | ||
# perf probe sdt_tcl:proc__entry | # perf probe sdt_tcl:proc__entry |
Версия от 16:44, 14 октября 2022
Userland Statically Defined Tracing
Некоторый софт позволяет добавлять статические точки трассировки (трейспоинты) для удобства его отладки в сложных местах где трудно сделать другие виды трассировки, улучшая т.н. observability системы.
Например, такая поддержка есть у некоторых языков (java, perl, php, python, ruby, tcl, nodejs, dotnet), приложений (mariadb, postgresql, couchdb, systemd-udev, sssd, ceph), библиотек (grpc, glibc, glib, zlib). У нас эти пакеты пока собраны без такой поддержки и требуют её включения.
Исторически эти трейспоинты восходят к Solaris Dtrace, а в Линукс впервые попали через SystemTap. Нужно отметить, что данная реализация USDT использует только хедер sys/sdt.h
предоставляемый SystemTap, но не использует прочий SystemTap функционал или инфраструктуру.
Сборка пакета с поддержкой usdt
Маинтайнеру зачастую достаточно сделать два изменения spec'а: 1) добавить
BuildRequires: systemtap-sdt-devel
который приносит необходимый Си хедер, и 2) добавить соответствующую опцию configure
, например (её название может отличаться):
%configure --enable-dtrace
Другие варианты: --with-dtrace
, --enable-systemtap
, --with-systemtap
.
В результате — в коде в точке трассировке добавляется один nop
не влияющий на производительность при отключенной трассировке, а в ELF бинарник в секцию .note.stapsdt
записывается описание каждого трейспоинта и его аргументов. Проверить их наличие можно командой eu-readelf --notes=.note.stapsdt путь-к-бинарнику
. Пример для трейспоинта с именем example:test (имеющим один аргумент) и находящимся в бинарнике ./example:
$ eu-readelf --notes=.note.stapsdt ./example Note section [30] '.note.stapsdt' of 68 bytes at offset 0x3174: Owner Data size Type stapsdt 45 Version: 3 PC: 0x1153, Base: 0x2004, Semaphore: 0 Provider: example, Name: test, Args: '8@%rax'
Использование
Есть три варианта использования этих трейспоинтов -- через eBPF, perf_event и ftrace -- все они потребуют рутовых привилегий и трассировка (по умолчанию) происходит для всей системы вцелом (или для указанного процесса).
Использование через eBPF
bcc-tools
В пакете bcc-tools
предоставляются следующие утилиты:
tplist
покажет список трейспоинтов:
# tplist -l /usr/lib64/libtcl8.6.so | grep entry /usr/lib64/libtcl8.6.so tcl:cmd__entry /usr/lib64/libtcl8.6.so tcl:proc__entry
bcc trace
трассировщик. Пример использования:
шелл-А# bcc trace 'u:/usr/lib64/libtcl8.6.so:cmd__entry "%s", arg1' PID TID COMM FUNC - шелл-Б$ tclsh шелл-Б% puts test шелл-А: 23036 23036 tclsh cmd__entry b'puts'
bpftrace
В пакете bpftrace
одноименная утилита (документация на англ.). Пример использования:
шелл-А# bpftrace -e 'usdt:/usr/lib64/libtcl8.6.so:cmd__entry { printf("%s\n", str(arg0)); }' Attaching 1 probe... шелл-Б$ tclsh шелл-Б% puts test шелл-А: puts
Использование через интерфейс perf_event
perf
В пакете perf
одноименная утилита, пример:
# perf buildid-cache --add /usr/lib64/libtcl8.6.so # perf list | grep sdt_ | grep proc__entry sdt_tcl:proc__entry [SDT event] # perf probe sdt_tcl:proc__entry Added new events: sdt_tcl:proc__entry (on %proc__entry in /usr/lib64/libtcl8.6.so) # perf record -e sdt_tcl:proc__entry -a -- tclsh % echo 'hello world' 'hello world' % ^D # perf script | head -1 tclsh 22814 [015] 686801.201230: sdt_tcl:proc__entry: (7f9950fdf04e) arg1=94274876797648 arg2=0 arg3=94274876480632
Использование через интерфейс ftrace
trace-cmd
В пакете trace-cmd
одноименная утилита. NB: Сначала необходимо зарегистрировать probe в ядре так же как для perf
и только потом использовать.
# perf buildid-cache --add /usr/lib64/libtcl8.6.so # perf probe sdt_tcl:proc__entry # trace-cmd list -e sdt sdt_tcl:proc__entry # trace-cmd record -e sdt_tcl:proc__entry -- tclsh % puts test test % ^D # trace-cmd report tclsh-23269 [013] 689825.345553: proc__entry: (7f72e1b8f04e) arg1=93884043869840 arg2=0 arg3=93884043553912
Доп. материалы
- https://leezhenghui.github.io/linux/2019/03/05/exploring-usdt-on-linux.html Exploring USDT Probes on Linux
- https://lwn.net/Articles/753601/ Using user-space tracepoints with BPF [2018]
- https://www.brendangregg.com/blog/2016-10-12/linux-bcc-nodejs-usdt.html Linux bcc/BPF Node.js USDT Tracing
- https://www.brendangregg.com/blog/2015-07-03/hacking-linux-usdt-ftrace.html Hacking Linux USDT with Ftrace
- https://www.brendangregg.com/perf.html#StaticUserTracing §6.5. Static User Tracing
- https://www.sourceware.org/systemtap/wiki/AddingUserSpaceProbingToApps Adding User Space Probing to an Application