Tracing/USDT

Материал из ALT Linux Wiki

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

Доп. материалы