Действительно структурированный вывод в strace (Эльвира Хабирова, OSSDEVCONF-2016) — различия между версиями
Материал из 0x1.tv
StasFomin (обсуждение | вклад) (→Видео) |
StasFomin (обсуждение | вклад) (Batch edit: replace PCRE (\n\n)+(\n) with \2) |
||
(не показаны 42 промежуточные версии этого же участника) | |||
== Аннотация == ;Докладчик: {{Speaker|Эльвира Хабирова}} <blockquote> <tt>strace</tt> ---— утилита для отладки программ. Она отображает сделанные отлаживаемым процессом <tt>tracee</tt> системные вызовы, пришедшие ему сигналы, изменения его состояния и пр. Вывод <tt>strace</tt> на данный момент нацелен на человекочитаемость и по этой причине тяжело поддается автоматической обработке. Кроме того, из-за отсутствия единой системы вывода в выводе могут присутствовать неточности, что еще сильнее усложняет задачу. Поэтому в рамках GSoC~ 2016 проблема автоматической обработки была решена разработкой такой единой системы. Как результат, стало возможным легко встраивать не только подсистемы любого формата вывода, но и дополнительные слои логики. </blockquote> == Видео == {{vimeoembed|185219718|800|450}} <!-- {{youtubelink|}} -->|I6k57JL4qvo}}{{letscomment}} == Слайды == [[File:Действительно структурированный вывод в strace (Эльвира Хабирова, OSSDEVCONF-2016).pdf|left|page=-|256px]] {{----}} == Расширенные тезисы == <latex> \subsection{=== Обзор проблемы} === <latex> В \EN{\emph{strace}} на входе и выходе из системного вызова вызывается ассоциированный с ним обработчик (декодер), которому передаются полученные из \EN{tracee} аргументы. Ранее, \EN{\emph{strace}} кроме того, что обрабатывал эти аргументы, еще и немедленно печатал их. На входе могла печататься только часть аргументов (до первого \EN{out}\footnote{ \EN{out} аргумент~--- аргумент, который указывает на участок памяти, в котором находятся данные, являющиеся выходными для вызываемой функции. Также существует понятие \EN{in-out} аргумента: такой аргумент указывает на место в памяти с данными, являющимися входными и выходными} аргумента). В случае, если это имеет смысл и если указан достаточный уровень подробности вывода, \EN{\emph{strace}} копирует из \EN{tracee} данные, находящиеся по указателям, переданным в аргументах, и печатает их. Этот процесс может быть весьма многоуровневым~--- в случае передачи массивов указателей на структуры, например. Дополнительно \EN{\emph{strace}} может собирать и печатать статистику по времени выполнения, печатать содержимое \EN{iovec} и проч. \EN{\emph{strace}} не содержал унифицированных средств по печати информации о системном вызове; каждый декодер самостоятельно обеспечивал тот формат вывода, который считал нужным (за исключением некоторых базовых вещей, таких как вывод строки, флагов, массивов, дескрипторов... Хотя и здесь есть исключения в случае отдельных декодеров, которым требуется нестандартный вывод). Далее рассмотрим несколько примеров существующих декодеров системных вызовов. Рассмотрим иллюстрацию: \begin{figure}[h!] \centering \begin{scriptsize} \begin{verbatim}accept4(3, {sa_family=AF_UNIX, sun_path="accept4.socket.connect"}, [110->25], SOCK_NONBLOCK|SOCK_CLOEXEC) = 5\end{verbatim} \end{scriptsize} \squeeze \caption{Пример отображения информации о системном вызове \EN{\emph{accept4}}}\label{fig:accept4} \squeeze \end{figure} ~\ref{fig:accept4}. \EN{\emph{accept4}} принимает в качестве второго аргумента указатель на структуру \EN{\emph{struct sockaddr}}, в качестве третьего~--- размер структуры аргумента, и в качестве четвертого набор фагов. В данном случае \EN{\emph{strace}} скопировал из \EN{tracee} структуру \EN{\emph{struct sockaddr}} и декодировал её согласно значению поля \EN{\emph{sa\_family}} (т.~е. интерпретировал последующие данные как поле \EN{\emph{sun\_path}}); также \EN{\emph{strace}} прочитал значение по указателю, переданному в аргументе \EN{\emph{addrlen}}, причём и на входе, и на выходе, так как это \EN{in-out} аргумент. Четвёртый аргумент декодирован как набор флагов. Перейдем к иллюстрации: \begin{figure}[h!] \centering \begin{scriptsize}\begin{verbatim}setitimer(ITIMER_REAL, {it_interval={0, 222222}, it_value={0, 111111}}, NULL) = 0\end{verbatim} \end{scriptsize} \squeeze \caption{Пример отображения информации о системном вызове \EN{\emph{setitimer}}}\label{fig:setitimer} \squeeze \end{figure} ~\ref{fig:setitimer}. В качестве второго и третьего аргументов \EN{\emph{setitimer}} принимает указатель на \EN{\emph{struct itimerval}}, который, в свою очередь, являет собой пару структур \EN{\emph{struct timeval}}. Заметим, что декодер системного вызова выводит имена полей \EN{\emph{struct itimerval}}, но не \EN{\emph{struct timeval}}. На иллюстрации~\ref{fig:pwritev} можно отметить сразу несколько особенностей вывода: \begin{figure}[h!] \centering \begin{scriptsize} \begin{verbatim} $ strace -etrace=pwritev -ewrite=1 -s2 ./preadv-pwritev ... pwritev(1, [{iov_base="01"..., iov_len=3}, {iov_base="34"..., iov_len=5}, ...], 3, 0) = 15 * 3 bytes in buffer 0 | 00000 30 31 32 012 | * 5 bytes in buffer 1 | 00000 33 34 35 36 37 34567 | * 7 bytes in buffer 2 | 00000 38 39 61 62 63 64 65 89abcde |\end{verbatim} \end{scriptsize} \squeeze \caption{Пример отображения информации о системном вызове \EN{\emph{pwritev}} с печатью содержимого \EN{iovec}}\label{fig:pwritev} \squeeze \end{figure} \begin{itemize} \item[--] Строки и массивы, если их размер превышает указанный в параметре \texttt{-s} (32 по умолчанию), сокращаются и терминируются многоточиями. \item[--] Для I/O вызовов существует возможность, посредством задания опции \texttt{-ewrite=1}/\texttt{-eread=1}, вывода содержимого данных, передаваемых в этих вызовах, в формате шестнадцатеричного дампа. \end{itemize} На следующей иллюстрации заметим нестандартный способ аббревиирования вывода массива переменных, который отличается от используемого в большинстве других системных вызовов многоточия. \begin{figure}[h!] \centering \begin{small} \begin{verbatim}execve("./execve", ["./execve"], [/* 41 vars */]) = 0\end{verbatim} \end{small} \squeeze \caption{Пример отображения информации о системном вызове \EN{\emph{execve}}}\label{fig:execve} \squeeze \end{figure} На иллюстрации~\ref{fig:execve}На следующей иллюстрации показан пример системного вызова \EN{\emph{prctl}}. \begin{figure}[h!] \centering \begin{small} \begin{verbatim}prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, {len=3, filter=[BPF_STMT(BPF_LD|BPF_W|BPF_ABS, 0), BPF_JUMP(BPF_JMP|BPF_K|BPF_JEQ, 0x3, 0, 0x1), BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW)]}) = 0\end{verbatim} \end{small} \squeeze \caption{Пример отображения информации о системном вызове \EN{\emph{prctl}} с \EN{\emph{PR\_SET\_SECCOMP}} в качестве аргумента \EN{\emph{option}}}\label{fig:prctl} \squeeze \end{figure} ~\ref{fig:prctl} То, какие из аргументов \EN{\emph{arg2}}, \EN{\emph{arg3}}, \EN{\emph{arg4}}, \EN{\emph{arg5}} выведет \EN{\emph{strace}} и в каком формате, определяется значением первого аргумента \EN{\emph{option}}. В данном случае это команда установки \EN{BPF}-фильтра \EN{\emph{seccomp}}. Другой особенностью данного примера является формат вывода команд \EN{BPF}, которые являют собой структуры, но для которых в \EN{\texttt{<linux/filter.h>}} определены макрокоманды для их определения в коде на языке Си; декодер системного вызова определяет по содержимому структур подходяющую макрокоманду и печатает соответствующую макрокоманду. На следующей иллюстрации отметим формат вывода третьего аргумента, \EN{\emph{vec}}, который представляет собой массив байт, из каждого из которых значащий только один бит. \begin{figure}[h!] \centering \begin{small} \begin{verbatim}mincore(0x2ba1f6293000, 131073, [11111111111111111111...]) = 0\end{verbatim} \end{small} \squeeze \caption{Пример отображения информации о системном вызове \EN{\emph{mincore}}}\label{fig:mincore} \squeeze \end{figure} На следующей иллюстрации интересен формат вывода, используемый для файловых дескрипторов (первый аргумент). \begin{figure}[h!] \centering \begin{small} \begin{verbatim}listen(3<TCP:[4490622]>, 1) = 0\end{verbatim} \end{small} \squeeze \caption{Пример отображения информации о системном вызове \EN{\emph{listen}}}\label{fig:listen} \squeeze \end{figure} А в примере на следующем рисунке~\ref{fig:rt_setsigprocmask}, можно отметить специфический формат, используемый для вывода маски сигналов. \begin{figure}[h!] \centering \begin{small} \begin{verbatim}rt_sigprocmask(SIG_SETMASK, NULL, [HUP INT QUIT ALRM TERM], 8) = 0\end{verbatim} \end{small} \squeeze \caption{Пример отображения информации о системном вызове \EN{\emph{rt\_setsigprocmask}}}\label{fig:rt_setsigprocmask} \squeeze \end{figure} На иллюстрации~\ref{fig:mincore} На иллюстрации~\ref{fig:listen} В </latex> === \subsection{Идея структурированного вывода} === <latex> Итак, количество техник вывода, применяемых в \EN{\emph{strace}}, с одной стороны, велико и разнообразно (вывод битовых масок, масок сигналов, различные варианты аббревиирования структур), с другой, всё же поддаётся классификации (есть некие общие правила вывода структур, указателей, массивов). В основе структурированного вывода лежит идея, что все особенности формата вывода можно оформить в виде \EN{reusable} примитивов и использовать для вывода только их. Пример преобразования декодера показан на иллюстрации: </latex> [[File:strace-lp0-conversion.svg|center]] Второй важной особенностью является введение промежуточного представления системного вызова: [[File:strace-scheme.svg|center]] <latex> Декодер заполняет это внутреннее представление, и оно может потом быть выведено независимо. %На данный момент код, выводящий его в определенном %формате, называется \EN{formatter}. Переход к структурированному выводу позволяет избежать многочисленных однотипных вызовов печати (запятые, скобки, знаки равенства) и связанных с этим потенциальных багов. Разделение процесса декодирования и вывода позволяет внедрить возможности, которые ранее были затруднительны в \item[--] И, главное, выделение процесса форматирования вывода в отдельную сущность позволило реализовать то, ради чего затевался переход на структурированный вывод~--- форматирование вывода в машиночитаемом виде. В качестве примера такого формата был выбран \EN{JSON}. Заложенная архитектура позволяет просто реализовывать дополнительные машиночитаемые и человекочитаемые синтаксисы. В качестве возможных вариантов есть \EN{pcap}/\EN{pcapng}~\cite{pcapng}, \EN{YAML}. \end{itemize} \subsection{</latex> === Текущее состояние} === <latex> Работы по переходу на структурированный вывод ещё не закончены. К настоящему моменту стабилизирован API структурного вывода~\cite{readme-structured}, сконвертировано примерно 65\% декодеров системных вызовов, реализованы выводы в форматах \EN{legacy} и \EN{JSON}, реализована базовая проверка, является ли вывод в формате \EN{JSON} корректным \EN{JSON} (проверка на отсутствие остатков непосредственных вызовов функций печати). Регулярно производится \EN{\texttt{git rebase}} на \EN{master}-ветку \EN{\emph{strace}}. Из несделанного~--- помимо оставшихся декодеров системных вызовов\footnote{Среди которых можно отметить системный вызов \EN{\emph{ioctl}}.}~--- отсутствие тестов для формата \EN{JSON}. Прогресс разработки можно отслеживать в соответствующем репозитории~\cite{structured-repo}. \begin{thebibliography}{9} \bibitem{pcapng} PcapNg draft specification \url{https://github.com/pcapng/pcapng} \bibitem{readme-structured} \EN{Structured output readme.} \url{https://github.com/lineprinter/strace/blob/structured/README-structured.md} \bibitem{structured-repo} \EN{Structured output branch repository.} \url{https://github.com/lineprinter/strace/tree/structured} \end{thebibliography} </latex> == Примечания и отзывы == <!-- <blockquote>[©]</blockquote> --> {{fblink|1782184895367857}} {{vklink|206}} <references/> [[Category:File:{{#setmainimage:Действительно структурированный вывод в strace (Эльвира Хабирова, OSSDEVCONF-2016]] [[Category:Open-source]] [[Category:Draft]])!.jpg}}|center|640px]] {{stats|disqus_comments=0|refresh_time=2021-08-31T16:58:03.923790|vimeo_comments=0|vimeo_plays=56|youtube_comments=0|youtube_plays=59}} [[Категория:OSSDEVCONF-2016]] [[Категория:Strace]] |
Текущая версия на 12:20, 4 сентября 2021
Содержание
Аннотация
- Докладчик
- Эльвира Хабирова
strace — утилита для отладки программ. Она отображает сделанные отлаживаемым процессом tracee системные вызовы, пришедшие ему сигналы, изменения его состояния и пр.
Вывод strace на данный момент нацелен на человекочитаемость и по этой причине тяжело поддается автоматической обработке.
Кроме того, из-за отсутствия единой системы вывода в выводе могут присутствовать неточности, что еще сильнее усложняет задачу.
Поэтому в рамках GSoC 2016 проблема автоматической обработки была решена разработкой такой единой системы.
Как результат, стало возможным легко встраивать не только подсистемы любого формата вывода, но и дополнительные слои логики.
Видео
Посмотрели доклад? Понравился? Напишите комментарий! Не согласны? Тем более напишите.
Слайды
Расширенные тезисы
Обзор проблемы
Идея структурированного вывода
Второй важной особенностью является введение промежуточного представления системного вызова:
Текущее состояние
Примечания и отзывы
Plays:115 Comments:0