Strace — новые возможности (Дмитрий Левин, OSSDEVCONF-2017) — различия между версиями
Материал из 0x1.tv
StasFomin (обсуждение | вклад) (Новая страница: «;{{SpeakerInfo}}: {{Speaker|Дмитрий Левин}} <blockquote> Strace — инструмент для отслеживания и влияния на вза…») |
StasFomin (обсуждение | вклад) |
||
== Thesis ==
=== Введение ===
strace как инструмент мониторинга взаимодействия пользовательских процессов с
ядром существует уже почти 26 лет и широко применяется для диагностики, отладки
и изучения поведения ПО. Многочисленные параметры управления фильтрацией дают
возможность пользователю strace легко и гибко настраивать отображение системных
вызовов и сигналов. С каждым выпуском strace таких возможностей становится
больше, а точность отображения — выше.
Начиная с версии 4.13, выпущенной летом прошлого года, расписание выпусков
новых версий strace синхронизировано с расписанием выпусков новых версий ядра
linux. Таким образом новые интерфейсы, добавляемые в релизы ядра linux,
сопровождаются соответствующими парсерами, добавляемыми в релизы strace.
Помимо многочисленных улучшений отображения системных вызовов, за минувший год
в strace было реализовано много нового и интересного.
=== System Call Specification ===
Синтаксис описания множества системных вызовов существенно расширился:
* В описании имён системных вызовов теперь поддерживаются регулярные выражения:
strace -e trace=/<i>regexp</i>
* В описании множества системных вызовов поддерживаются описания, которым не соответствует ни одного системного вызова:
strace -e trace=?<i>set</i>
* Имена классов системных вызовов теперь начинаются с префикса %:
strace -e trace=%<i>class</i> \\
Прежний способ именования классов без префикса % ещё поддерживается, но уже считается устаревшим.
* Добавлены новые классы системных вызовов:
;%stat: stat, stat64, oldstat и их вариации;
;%lstat: lstat, lstat64, oldlstat и их вариации;
;%fstat: fstat, fstat64, fstatat64, newfstatat, oldfstat и их вариации;
;%%stat: stat, lstat, fstat, fstatat, statx и их вариации;
;%statfs: эквивалент /\textasciicircum(.*_)?statv?fs;
;%fstatfs: эквивалент /fstatv?fs;
;%statfs: эквивалент /statv?fs|fsstat|ustat.
=== System call tampering и fault injection ===
Механизм syscall fault injection, прототип которого подробно рассматривался на
этой конференции год назад, был доработан и включён в strace, начиная с версии
4.15, выпущенной в декабре прошлого года. По сравнению с прототипом, синтаксис
syscall fault injection изменился и выглядит следующим образом:
-e fault=<i>set</i>[:error=<i>errno</i>][:when=<i>expr</i>]
Начиная с версии 4.16, выпущенной в феврале прошлого года, реализован более
общий механизм вмешательства в системные вызовы, который, помимо syscall fault
injection, позволяет осуществлять syscall return value injection и signal
injection. Интерфейс этого нового механизма выглядит следующим образом:
-e inject=<i>set</i>[:error=<i>errno</i>|:retval=<i>value</i>][:signal=<i>sig</i>][:when=<i>expr</i>]
=== Netlink socket parsers ===
В strace версии 4.19, выпущенной в начале сентября, реализовано детальное
декодирование трафика, проходящего через netlink sockets, что позволяет
использовать strace для отладки приложений, работающих с netlink-протоколами.
Так, например, может выглядеть вывод парсера трафика семейства NETLINK_ROUTE:
<latex>
{\texttt\tiny
\$ hshrun --mount=/proc -- strace -e trace=sendto,recvmsg ip r l t all \\
\fontsize{4pt}{4pt}\selectfont
sendto(3, \{\{len=40, type=RTM_GETROUTE, flags=NLM_F_REQUEST|NLM_F_DUMP, \\seq=1357924680, pid=0\}, \{rtm_family=AF_UNSPEC, rtm_dst_len=0, rtm_src_len=0, rtm_tos=0,\\ rtm_table=RT_TABLE_UNSPEC, rtm_protocol=RTPROT_UNSPEC, \\rtm_scope=RT_SCOPE_UNIVERSE, rtm_type=RTN_UNSPEC, rtm_flags=0\}, \{nla_len=0, \\nla_type=RTA_UNSPEC\}\}, 40, 0, NULL, 0) = 40 \\
recvmsg(3, \{msg_name=\{sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000\}, \\msg_namelen=12, msg_iov=[\{iov_base=[\{\{len=60, type=RTM_NEWROUTE, flags=NLM_F_MULTI, seq=1357924680, pid=12345\}, \{rtm_family=AF_INET, rtm_dst_len=32, rtm_src_len=0, rtm_tos=0, rtm_table=RT_TABLE_LOCAL, rtm_protocol=RTPROT_KERNEL, rtm_scope=RT_SCOPE_LINK, rtm_type=RTN_BROADCAST, rtm_flags=0\}, [\{\{nla_len=8, nla_type=RTA_TABLE\}, \\RT_TABLE_LOCAL\}, \{\{nla_len=8, nla_type=RTA_DST\}, 127.0.0.0\}, \{\{nla_len=8, nla_type=\\RTA_PREFSRC\}, 127.0.0.1\}, \{\{nla_len=8, nla_type=RTA_OIF\}, if_nametoindex("lo")\}]\}, \{\{len=60, type=RTM_NEWROUTE, flags=NLM_F_MULTI, seq=1357924680, pid=12345\}, \{rtm_family=\\AF_INET, rtm_dst_len=8, rtm_src_len=0, rtm_tos=0, rtm_table=RT_TABLE_LOCAL, \\rtm_protocol=RTPROT_KERNEL, rtm_scope=RT_SCOPE_HOST, rtm_type=RTN_LOCAL, \\rtm_flags=0\}, [\{\{nla_len=8, nla_type=RTA_TABLE\}, RT_TABLE_LOCAL\}, \{\{nla_len=8, nla_type=\\RTA_DST\}, 127.0.0.0\}, \{\{nla_len=8, nla_type=RTA_PREFSRC\}, 127.0.0.1\}, \{\{nla_len=8, nla_type=\\RTA_OIF\}, if_nametoindex("lo")\}]\}, \{\{len=60, type=RTM_NEWROUTE, flags=NLM_F_MULTI, seq=1357924680, pid=12345\}, \{rtm_family=AF_INET, rtm_dst_len=32, rtm_src_len=0, rtm_tos=0, rtm_table=RT_TABLE_LOCAL, rtm_protocol=RTPROT_KERNEL, rtm_scope=RT_SCOPE_HOST, rtm_type=RTN_LOCAL, rtm_flags=0\}, [\{\{nla_len=8, nla_type=RTA_TABLE\}, \\RT_TABLE_LOCAL\}, \{\{nla_len=8, nla_type=RTA_DST\}, 127.0.0.1\}, \{\{nla_len=8, nla_type=\\RTA_PREFSRC\}, 127.0.0.1\}, \{\{nla_len=8, nla_type=RTA_OIF\}, if_nametoindex("lo")\}]\}, \{\{len=60, type=RTM_NEWROUTE, flags=NLM_F_MULTI, seq=1357924680, pid=12345\}, \{rtm_family=\\AF_INET, rtm_dst_len=32, rtm_src_len=0, rtm_tos=0, rtm_table=RT_TABLE_LOCAL, \\rtm_protocol=RTPROT_KERNEL, rtm_scope=RT_SCOPE_LINK, rtm_type=RTN_BROADCAST, rtm_flags=0\}, [\{\{nla_len=8, nla_type=RTA_TABLE\}, RT_TABLE_LOCAL\}, \{\{nla_len=8, nla_type=\\RTA_DST\}, 127.255.255.255\}, \{\{nla_len=8, nla_type=RTA_PREFSRC\}, 127.0.0.1\}, \{\{nla_len=8, nla_type=RTA_OIF\}, if_nametoindex("lo")\}]\}], iov_len=32768\}], msg_iovlen=1, msg_controllen=0, msg_flags=0\}, 0) = 240 \\
broadcast 127.0.0.0 dev lo table local proto kernel scope link src 127.0.0.1 \\
local 127.0.0.0/8 dev lo table local proto kernel scope host src 127.0.0.1 \\
local 127.0.0.1 dev lo table local proto kernel scope host src 127.0.0.1 \\
broadcast 127.255.255.255 dev lo table local proto kernel scope link src 127.0.0.1 \\
recvmsg(3, \{msg_name=\{sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000\}, \\msg_namelen=12, msg_iov=[\{iov_base=\{\{len=20, type=NLMSG_DONE, flags=NLM_F_MULTI, seq=\\1505349241, pid=12345\}, 0\}, iov_len=32768\}], msg_iovlen=1, msg_controllen=0, msg_flags=0\}, 0) = 20
}
</latex>
=== Advanced syscall filtering syntax ===
В рамках GSoC 2017 Николай Марчук реализовал прототип ещё более гибкого
синтаксиса фильтрации системных вызовов:
[<b><i>action</b></i>(]<b><i>filter_expression</b></i>[;<b><i>arg1</b></i>[;<b><i>arg2</b></i>...]][)]
где
;action: это <b>trace</b>, <b>abbrev</b>, <b>verbose</b>, <b>raw</b>, <b>read</b>, <b>write</b>, <b>fault</b>, <b>inject</b>, или <b>stacktrace</b>;
;arnN: это аргументы <b><i>action</b></i>;
;filter_expression: состоит из комбинации фильтров, каждый их которых, в свою очередь, состоит из имени фильтра и аргументов фильтра.
Поддерживаются следующие фильтры:
;syscall <i>set</i>: множество системных вызовов, соответствующих описанию <b><i>set</b></i>.
;fd <i>fd1</i>…: множество системных вызовов, оперирующих дескрипторами, соответствующими описанию <b><i>fd1</b></i>…;
;path <i>path</i>: множество системных вызовов, оперирующих файлами, соответствующими описанию <b><i>path</b></i>.
Комбинация фильтров осуществляется с помощью операторов <b>not</b>, <b>and</b>, <b>or</b> и круглых скобок.
Более подробно новый синтаксис описан в strace(1).
=== Advanced syscall tampering and filtering with Lua/LuaJIT ===
В рамках GSoC 2017 Виктор Крапивенский реализовал прототип Lua-скриптинга,
который позволяет не только производить фильтрацию и подмену системных вызовов
с большей гибкостью, но и производить success injection с сохранением семантики
системного вызова, которая, в частности, может заключаться в записи
определённых данных в адресное пространство процесса.
Подробнее об этом расскажет автор в своём докладе.
=== Advanced syscall information tool ===
В рамках GSoC 2017 Эдгар Казиахмедов реализовал прототип новой утилиты asinfo,
предназначенной для получения разнообразной информации о системных вызовых.
Подробнее об этом расскажет автор в своём докладе.
{{LinksSection}}
<!-- <blockquote>[©]</blockquote> -->
<references/>
[[Категория:OSSDEVCONF-2017]] |
Версия 19:53, 3 октября 2017
- Докладчик
- Дмитрий Левин
Strace — инструмент для отслеживания и влияния на взаимодействия пользовательских процессов и ядра Linux: системных вызовов, сигналов и изменений состояния процесса.
За минувший год в strace реализовано много нового и интересного.
Содержание
Видео
Презентация
Thesis
Введение
strace как инструмент мониторинга взаимодействия пользовательских процессов с ядром существует уже почти 26 лет и широко применяется для диагностики, отладки и изучения поведения ПО. Многочисленные параметры управления фильтрацией дают возможность пользователю strace легко и гибко настраивать отображение системных вызовов и сигналов. С каждым выпуском strace таких возможностей становится больше, а точность отображения — выше.
Начиная с версии 4.13, выпущенной летом прошлого года, расписание выпусков новых версий strace синхронизировано с расписанием выпусков новых версий ядра linux. Таким образом новые интерфейсы, добавляемые в релизы ядра linux, сопровождаются соответствующими парсерами, добавляемыми в релизы strace.
Помимо многочисленных улучшений отображения системных вызовов, за минувший год в strace было реализовано много нового и интересного.
System Call Specification
Синтаксис описания множества системных вызовов существенно расширился:
- В описании имён системных вызовов теперь поддерживаются регулярные выражения:
strace -e trace=/regexp
- В описании множества системных вызовов поддерживаются описания, которым не соответствует ни одного системного вызова:
strace -e trace=?set
- Имена классов системных вызовов теперь начинаются с префикса %:
strace -e trace=%class \\
Прежний способ именования классов без префикса % ещё поддерживается, но уже считается устаревшим.
- Добавлены новые классы системных вызовов:
- %stat
- stat, stat64, oldstat и их вариации;
- %lstat
- lstat, lstat64, oldlstat и их вариации;
- %fstat
- fstat, fstat64, fstatat64, newfstatat, oldfstat и их вариации;
- %%stat
- stat, lstat, fstat, fstatat, statx и их вариации;
- %statfs
- эквивалент /\textasciicircum(.*_)?statv?fs;
- %fstatfs
- эквивалент /fstatv?fs;
- %statfs
- эквивалент /statv?fs|fsstat|ustat.
System call tampering и fault injection
Механизм syscall fault injection, прототип которого подробно рассматривался на этой конференции год назад, был доработан и включён в strace, начиная с версии 4.15, выпущенной в декабре прошлого года. По сравнению с прототипом, синтаксис syscall fault injection изменился и выглядит следующим образом:
-e fault=set[:error=errno][:when=expr]
Начиная с версии 4.16, выпущенной в феврале прошлого года, реализован более общий механизм вмешательства в системные вызовы, который, помимо syscall fault injection, позволяет осуществлять syscall return value injection и signal injection. Интерфейс этого нового механизма выглядит следующим образом:
-e inject=set[:error=errno|:retval=value][:signal=sig][:when=expr]
Netlink socket parsers
В strace версии 4.19, выпущенной в начале сентября, реализовано детальное декодирование трафика, проходящего через netlink sockets, что позволяет использовать strace для отладки приложений, работающих с netlink-протоколами. Так, например, может выглядеть вывод парсера трафика семейства NETLINK_ROUTE:
Advanced syscall filtering syntax
В рамках GSoC 2017 Николай Марчук реализовал прототип ещё более гибкого синтаксиса фильтрации системных вызовов:
[action</b>(]<b>filter_expression</b>[;<b>arg1</b>[;<b>arg2</b>...]][)]
где
- action
- это <b>trace, abbrev, verbose, raw, read, write, fault, inject, или stacktrace;
- arnN
- это аргументы action</b>;
- filter_expression
- состоит из комбинации фильтров, каждый их которых, в свою очередь, состоит из имени фильтра и аргументов фильтра.
Поддерживаются следующие фильтры:
- syscall set
- множество системных вызовов, соответствующих описанию <b>set</b>.
- fd fd1…
- множество системных вызовов, оперирующих дескрипторами, соответствующими описанию <b>fd1</b>…;
- path path
- множество системных вызовов, оперирующих файлами, соответствующими описанию <b>path</b>.
Комбинация фильтров осуществляется с помощью операторов <b>not, and, or и круглых скобок.
Более подробно новый синтаксис описан в strace(1).
Advanced syscall tampering and filtering with Lua/LuaJIT
В рамках GSoC 2017 Виктор Крапивенский реализовал прототип Lua-скриптинга, который позволяет не только производить фильтрацию и подмену системных вызовов с большей гибкостью, но и производить success injection с сохранением семантики системного вызова, которая, в частности, может заключаться в записи определённых данных в адресное пространство процесса. Подробнее об этом расскажет автор в своём докладе.
Advanced syscall information tool
В рамках GSoC 2017 Эдгар Казиахмедов реализовал прототип новой утилиты asinfo, предназначенной для получения разнообразной информации о системных вызовых. Подробнее об этом расскажет автор в своём докладе.