Modern strace
LVEE 2019
Введение
strace как инструмент мониторинга взаимодействия пользовательских процессов с ядром существует уже почти 28 лет и широко применяется для диагностики, отладки и изучения поведения ПО. Многочисленные параметры управления фильтрацией дают возможность пользователю strace легко и гибко настраивать отображение системных вызовов и сигналов. С каждым выпуском strace таких возможностей становится больше, а точность отображения — выше.
Начиная с версии 4.13, выпущенной в июле 2016 года, расписание выпусков новых версий strace синхронизировано с расписанием выпусков новых версий ядра linux. Таким образом новые интерфейсы, добавляемые в релизы ядра linux, сопровождаются соответствующими парсерами, добавляемыми в релизы strace.
strace относится к традиционным инструментам, и пользователи со стажем зачастую не подозревают о новых возможностях, появившихся в strace за последние несколько лет, таких как
- отслеживание файловых путей: параметр ;
- отслеживание сетевых протоколов: параметр ;
- отслеживание стека вызовов: параметр ;
- сбор статистики по времени, проведённому отслеживаемыми процессами в системных вызовах: параметр ;
- фильтрация системных вызовов по файловым путям: параметр ;
- фильтрация системных вызовов по именам: с помощью регулярных выражений и новых классов системных вызовов;
- модификация системных вызовов: инъекции ошибок, кодов возврата, сигналов, и задержек.
Отслеживание файловых путей и фильтрация по файловым путям
Начиная с версии 4.7, выпущенной в мае 2012 года, реализована возможность отслеживания файловых путей, соответствующих дескрипторам, с помощью параметра .
В той же версии была реализована возможность фильтрации системных вызовов по файловым путям, соответствующим аргументам системных вызовов и файловым дескрипторам, с помощью параметра .
Отслеживание сетевых протоколов и устройств
Начиная с версии 4.10, выпущенной в марте 2015 года, реализована возможность отслеживания характеристик сетевых протоколов, соответствующих дескрипторам сокетов, с помощью параметра .
Начиная с версии 4.22, выпущенной в апреле этого года, с помощью этого же параметра можно отслеживать и характеристики устройств.
Отслеживание стека вызовов
Начиная с версии 4.9, выпущенной в августе 2014 года, реализована экспериментальная возможность отслеживания стека вызовов функций с помощью параметра . Начиная с версии 4.23, выпущенной в июне этого года, усовершенствованная реализация этой возможности с использованием библиотеки libdw уже не носит экспериментальный статус.
Cбор статистики
Начиная с версии 4.9, выпущенной в августе 2014 года, реализована возможность сбора статистики по времени, проведённому отслеживаемыми процессами в системных вызовах, с помощью параметра .
Фильтрация системных вызовов по именам
Начиная с версии 4.17, выпущенной в мае 2017 года, синтаксис описания множества системных вызовов существенно расширился.
В описании имён системных вызовов теперь поддерживаются регулярные выражения:
В описании множества системных вызовов поддерживаются описания, которым не соответствует ни одного системного вызова:
Имена классов системных вызовов теперь начинаются с префикса :
Прежний способ именования классов без префикса поддерживается, но уже считается устаревшим и не рекомендуется для применения.
Добавлены новые классы системных вызовов семейства stat:
Модификация системных вызовов
Начиная с версии 4.15, выпущенной в декабре 2016 года, реализован механизм инъекций ошибок в системные вызовы.
Синтаксис syscall fault injection выглядит следующим образом:
Начиная с версии 4.16, выпущенной в феврале 2017 года, реализован более общий механизм вмешательства в системные вызовы, который, помимо инъекций ошибок, позволяет осуществлять инъекции кодов возврата и сигналов, а начиная с версии 4.22, выпущенной в апреле 2018 года, ещё и инъекции задержек.
Интерфейс этого нового механизма выглядит следующим образом:
где могут принимать следующие значения:
- либо —
инъекция ошибки либо кода возврата; - —
подменяемый системный вызов для инъекции ошибок либо кода возврата; - —
инъекция сигнала; - —
инъекция задержки перед системным вызовом; - —
инъекция задержки после системного вызова; - —
правило применения инъекции.
Пример инъекции ошибки:
!http://www.codecogs.com/png.latex?\textstyle%20strace%20-e%20trace=/open%20-e%20inject=/open:when=3:error=EACCES%20cat%20/dev/null%0D%0Aopenat(AT_FDCWD,%20%22/etc/ld.so.cache%22,%20O_RDONLY%7CO_CLOEXEC)%20=%203%0D%0Aopenat(AT_FDCWD,%20%22/lib64/libc.so.6%22,%20O_RDONLY%7CO_CLOEXEC)%20=%203%0D%0Aopenat(AT_FDCWD,%20%22/dev/null%22,%20O_RDONLY)%20=%20-1%20EACCES%20(Permission%20denied)%20(INJECTED)%0D%0Acat:%20/dev/null:%20Permission%20denied%0D%0A+++%20exited%20with%201%20+++%0D%0A%0D%0A%D0%9F%D1%80%D0%B8%D0%BC%D0%B5%D1%80%20%D0%B8%D0%BD%D1%8A%D0%B5%D0%BA%D1%86%D0%B8%D0%B8%20%D0%B7%D0%B0%D0%B4%D0%B5%D1%80%D0%B6%D0%BA%D0%B8:%0D%0A%0D%0Abc.! dd if=/dev/zero of=/dev/null bs=1M count=10
10+0 records in
10+0 records out
10485760 bytes (10 MB, 10 MiB) copied, 0.00211354 s,
5.0 GB/s
$ strace -e inject=write:delay_exit=100000 -e write -o /dev/null \
dd if=/dev/zero of=/dev/null bs=1M count=10
10+0 records in
10+0 records out
10485760 bytes (10 MB, 10 MiB) copied, 1.10658 s,
9.5 MB/s
Abstract licensed under Creative Commons Attribution-ShareAlike 3.0 license
Back