Представлен экспериментальный выпуск инструментария динамической отладки DTrace для Linux 2.0.0-1.14, реализованный в виде работающего в пространстве пользователя процесса, использующего подсистему eBPF и штатные механизмы трассировки, предоставляемых ядром Linux. По функциональности реализация DTrace на базе eBPF близка к первой реализации DTrace для Linux, выполненной в форме модуля ядра. Код проекта распространяется под лицензией GPLv2.
Инструментарий может использоваться со штатными ядрами Linux, поддерживающими BPF. Для работы требуется библиотека libctf с реализацией поддержки отладочного формата CTF (Compact Type Format), которая входит в состав пакета binutils, начиная с выпуска 2.40, или библиотека libdtrace-ctf, портированная из Solaris. Опционально предлагается два патча к ядру 6.7, позволяющих задействовать расширенные возможности для получения дополнительных данных о модулях и ядре.
Технология DTrace была разработана для решения задач по динамической трассировке ядра и конечных приложений в операционной системе Solaris. DTrace даёт пользователю возможность детально отслеживать поведение системы и в режиме реального времени производить диагностику проблем. В процессе отладки DTrace не влияет на работу исследуемых приложений и никак не отражается на их производительности, что позволяет организовать анализ работающих систем на лету. Из сильных сторон DTrace отмечается высокоуровневый язык D, похожий на AWK, на котором значительно проще создавать сценарии трассировки, чем при применении предлагаемых для eBPF средств написания обработчиков на языках C, Python и Lua с внешними библиотеками.
Основные возможности:
- Доступные провайдеры:
- cpc (CPU Performacne Counter) – получение информации о производительности.
- dtrace – обработчики BEGIN, END и ERROR, запускаемые перед или после других проверок, а также при возникновении ошибок.
- fbt (Function Boundary Tracing) – отслеживание обращений к функциям ядра.
- lockstat – отслеживание состояния блокировок.
- pid – отслеживание обращений к функциям в процессах, работающих в пространстве пользователя.
- proc – отслеживание активности, связанной с процессами, такой как запуск и завершение работы (fork, exec, exit, fault).
- profile – сохранение статистики о производительности через указанные промежутки времени.
- sdt, rawtp – статическая трассировка ядра (SDT – Statically Defined Tracing).
- usdt: статическая трассировка приложений (USDT – Userspace Statically Defined Tracing)
- sched – отслеживание распределения ресурсов CPU.
- sycall – отслеживание входа в системные вызовы и выхода из них.
- Агрегирование собираемых данных: возможность применения агрегатных функций (avg, count, llquantize, lquantize, max, min, quantize, stddev и sum) и агрегатных действий (clear, normalize, normalize, printa). Поддержка сохранения результатов применения агрегатных функций в обычных и ассоциативных массивах.
- Поддержка спекулятивной трассировки, позволяющей эфемерно отслеживать данные, решая какие из них следует фиксировать в буфере трассировки, а какие отбрасывать. Доступны функции: speculation, speculate, commit и discard.
- Поддержка глобальных и локальных переменных, TLS (Thread-Local Storage), ассоциативных массивов и строк.
- Предоставление встроенных переменных: arg0 – arg9, args[], caller, curcpu, curthread, epid, errno, execname, gid, id, pid, ppid, probefunc, probemod, probename, probeprov, stackdepth, tid, timestamp, ucaller, uid, uregs[], ustackdepth, walltimestamp.
- Поддержка действий: exit, freopen, ftruncate, mod, printa, printf, raise, setopt, stack, sym, system, trace, tracemem, uaddr, umod, ustack и usym.
- Наличие встроенных функций:
alloca, basename, bcopy, copyin, copyinstr, copyinto, copyout, copyoutstr, dirname, getmajor, getminor, htonl, htonll, htons, index, inet_ntoa, lltostr, mutex_owned, mutex_owner, mutex_type_adaptive, mutex_type_spin, ntohl, ntohll, ntohs, progenyof, rand, rindex, rw_iswriter, rw_read_held, rw_write_held, strchr, strjoin, strlen, strrchr, strstr, strtok, substr. - Наличие счётчиков данных, не попадающих в буферы трассировки.
- Поддержка компиляции сценариев трассировки на языке D в форму BPF-программ.
- Предкомпиляция функций BPF для библиотечных вызовов.
- Опция bpflog для получения лога верификации загружаемых программ BPF.
- Динамическая генерация кода и предкомпиляция кода для повторного использования в BPF-программах.
Изменения в новой версии:
- В провайдер pid, применяемый для отслеживания процессов в пространстве пользователя, добавлена поддержка отслеживания выполнения инструкций по их смещению в коде.
- Добавлена поддержка использования функций stack() и ustack() для агрегирования собираемых данных.
- Возможность удаления из ассоциативных массивов элементов любых типов через присвоение литерала 0.
- Добавлено действие print для вывода структурированных данных с аннотациями типов.
- Добавлены новые встроенные функции cleanpath(), d_path() и link_ntop().
- Добавлен параметр “-xcpu”, позволяющий привязать проверки к определённым CPU.
- Добавлен параметр “-xlockmem” для ограничения размера памяти.
- Обеспечена возможность сохранения данных трассировки процессов (USDT) между перезапусками dtprobed.
- Поддержка механизма BTF (BPF Type Format), предоставляющего информацию для проверки типов в псевдокоде BPF.
- Возможность использования скрипта configure для сборки.