Tracing/USDT: различия между версиями

Материал из ALT Linux Wiki
м (→‎Использование: форматирование)
Строка 27: Строка 27:
Есть три варианта использования этих трейспоинтов -- через eBPF, perf_event и ftrace -- все они потребуют рутовых привилегий и трассировка (по умолчанию) происходит для всей системы вцелом (или для указанного процесса).
Есть три варианта использования этих трейспоинтов -- через eBPF, perf_event и ftrace -- все они потребуют рутовых привилегий и трассировка (по умолчанию) происходит для всей системы вцелом (или для указанного процесса).


Использование через ''eBPF'':
=== Использование через ''eBPF'' ===
* В пакете <code>bcc-tools</code> предоставляются следующие утилиты:
==== bcc-tools ====
** <code>tplist</code> покажет список трейспоинтов:
В пакете <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> трассировщик. Пример использования:
* <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'


* В пакете <code>bpftrace</code> одноименная утилита ([https://github.com/iovisor/bpftrace/blob/master/docs/reference%20guide.md документация на англ.]). Пример использования:
==== 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'' ===
* В пакете <code>perf</code> одноименная утилита, пример:
==== 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'' ===
* В пакете <code>trace-cmd</code> одноименная утилита. NB: Сначала необходимо зарегистрировать probe в ядре так же как для <code>perf</code> и только потом использовать.
==== 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

Версия от 13: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

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