Действительно структурированный вывод в strace (Эльвира Хабирова, OSSDEVCONF-2016) — различия между версиями

Материал из 0x1.tv

(Видео)
(Batch edit: replace PCRE (\n\n)+(\n) with \2)
 
(не показана одна промежуточная версия этого же участника)
== Аннотация ==
;Докладчик: {{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

Аннотация

Докладчик
Эльвира Хабирова.jpg
Эльвира Хабирова

strace — утилита для отладки программ. Она отображает сделанные отлаживаемым процессом tracee системные вызовы, пришедшие ему сигналы, изменения его состояния и пр.

Вывод strace на данный момент нацелен на человекочитаемость и по этой причине тяжело поддается автоматической обработке.

Кроме того, из-за отсутствия единой системы вывода в выводе могут присутствовать неточности, что еще сильнее усложняет задачу.

Поэтому в рамках GSoC 2016 проблема автоматической обработки была решена разработкой такой единой системы.

Как результат, стало возможным легко встраивать не только подсистемы любого формата вывода, но и дополнительные слои логики.

Видео

on youtube

Посмотрели доклад? Понравился? Напишите комментарий! Не согласны? Тем более напишите.

Слайды

Действительно структурированный вывод в strace (Эльвира Хабирова, OSSDEVCONF-2016).pdf Действительно структурированный вывод в strace (Эльвира Хабирова, OSSDEVCONF-2016).pdf Действительно структурированный вывод в strace (Эльвира Хабирова, OSSDEVCONF-2016).pdf Действительно структурированный вывод в strace (Эльвира Хабирова, OSSDEVCONF-2016).pdf Действительно структурированный вывод в strace (Эльвира Хабирова, OSSDEVCONF-2016).pdf Действительно структурированный вывод в strace (Эльвира Хабирова, OSSDEVCONF-2016).pdf Действительно структурированный вывод в strace (Эльвира Хабирова, OSSDEVCONF-2016).pdf Действительно структурированный вывод в strace (Эльвира Хабирова, OSSDEVCONF-2016).pdf Действительно структурированный вывод в strace (Эльвира Хабирова, OSSDEVCONF-2016).pdf Действительно структурированный вывод в strace (Эльвира Хабирова, OSSDEVCONF-2016).pdf Действительно структурированный вывод в strace (Эльвира Хабирова, OSSDEVCONF-2016).pdf Действительно структурированный вывод в strace (Эльвира Хабирова, OSSDEVCONF-2016).pdf Действительно структурированный вывод в strace (Эльвира Хабирова, OSSDEVCONF-2016).pdf Действительно структурированный вывод в strace (Эльвира Хабирова, OSSDEVCONF-2016).pdf Действительно структурированный вывод в strace (Эльвира Хабирова, OSSDEVCONF-2016).pdf Действительно структурированный вывод в strace (Эльвира Хабирова, OSSDEVCONF-2016).pdf Действительно структурированный вывод в strace (Эльвира Хабирова, OSSDEVCONF-2016).pdf Действительно структурированный вывод в strace (Эльвира Хабирова, OSSDEVCONF-2016).pdf Действительно структурированный вывод в strace (Эльвира Хабирова, OSSDEVCONF-2016).pdf Действительно структурированный вывод в strace (Эльвира Хабирова, OSSDEVCONF-2016).pdf Действительно структурированный вывод в strace (Эльвира Хабирова, OSSDEVCONF-2016).pdf

Расширенные тезисы

Обзор проблемы


Идея структурированного вывода

Strace-lp0-conversion.svg

Второй важной особенностью является введение промежуточного представления системного вызова:

Strace-scheme.svg

Текущее состояние


Примечания и отзывы

Действительно структурированный вывод в strace (Эльвира Хабирова, OSSDEVCONF-2016)!.jpg

Plays:115   Comments:0