Документация
ОС Аврора 5.1.4

Утилита strace

Утилита strace отслеживает системные вызовы и сигналы.

strace – инструмент диагностики, обучения и отладки. Он очень полезен для решения проблем с программами, для которых источник недоступен, поскольку их не нужно перекомпилировать для отслеживания.

Поскольку системные вызовы и сигналы являются событиями, которые происходят в интерфейсе пользователя/ядра, тщательное изучение этой границы очень полезно для изоляции ошибок, проверки работоспособности и попыток получения условий гонки.

Установка утилиты

Для установки утилиты на устройство следует выполнить следующее:

  1. Подключиться к устройству по ssh. По умолчанию имя пользователя defaultuser.

    ssh defaultuser@<device_ip>
    
  2. Убедиться, что интернет и репозитории доступны:

    ssu domain
    

    Пример успешного вывода:

    Device domain is currently: sales
    

    Если домен не указан, следует его настроить. Если вывод успешен, можно переходить к следующему пункту.

  3. Найти пакет strace:

    pkcon search strace
    

    В списке доступных пакетов должен появиться strace.

  4. Установить пакет strace:

    devel-su pkcon install strace
    

Синопсис команды

strace [-ACdffhikqrtttTvVxxy] [-ACdffhiqrtttTvVxxy] [-I n]
           [-b execve] [-e expr]... [-a column] [-o file] [-s strsize]
           [-X format] [-P path]... [-p pid]... { -p pid | [-D]
           [-E var[=val]]... [-u username] command [args] }

strace -c [-df] [-I n] [-b execve] [-e expr]... [-O overhead]
           [-S sortby] [-P path]... [-p pid]... { -p pid | [-D]
           [-E var[=val]]... [-u username] command [args] }

В простейшем случае strace запускает указанную команду и работает до её завершения. Она перехватывает и записывает системные вызовы, вызываемые процессом, и сигналы, принимаемые процессом. Имя каждого системного вызова, его аргументы и возвращаемое значение выводятся по стандартному пути вывода ошибок или в файл, указанный с помощью опции -o.

strace без аргументов записывает все сообщения трассировки событий STREAMS от всех драйверов и модулей в свой стандартный вывод. Эти сообщения получены из драйвера журнала STREAMS. Если аргументы предоставлены, они должны быть в триплетах в форме mid, sid, level, где mid – это идентификационный номер модуля STREAMS, sid – это номер sub-ID, а level – уровень приоритета трассировки. Каждый триплет указывает, что сообщения трассировки должны быть получены от данного модуля/драйвера, идентификатора подчинённого (обычно указывающего на вспомогательное устройство) и уровня приоритета, равного или меньшего, чем данный уровень. Маркер all может использоваться для любого члена, чтобы указать отсутствие ограничений для этого атрибута.

Формат каждого вывода сообщения трассировки:

<seq> <time> <ticks> <level> <flags> <mid> <sid> <text>
  • <seq> – порядковый номер трассировки;
  • <time> – время сообщения в hh:mm:ss;
  • <ticks> – время сообщения в машинных тиках с момента загрузки;
  • <level> – уровень приоритета трассировки;
  • <flags> – E: сообщение также находится в журнале ошибок, F: указывает на фатальную ошибку, N: письмо было отправлено системному администратору (жестко закодировано как root);
  • <mid> – идентификационный номер модуля источника;
  • <sid> – субидентификационный номер источника sub-ID;
  • <text> – форматированный текст сообщения трассировки.

После запуска strace продолжит выполнение до тех пор, пока пользователь не прекратит работу.

Примеры

В следующем примере выводятся все сообщения трассировки от модуля или драйвера с идентификатором модуля 41:

strace  41 all all

В следующем примере выводятся сообщения трассировки для драйвера или модуля с идентификатором 41 и субидентификаторами 01 или 2:

strace  41 0 1  41 1 1  41 2 0

Сообщения для субидентификаторов 0 и 1 должны иметь уровень трассировки меньше или равный 1.

Сообщения для субидентификатора 2 должны иметь уровень трассировки 0.

Особенности работы strace и обозначения в трассировке стека

Каждая строка в трассировке содержит имя системного вызова, сопровождаемое его аргументами в скобках и его возвращаемым значением.

Пример использования команды cat /dev/null:

open("/dev/null", O_RDONLY) = 3

К ошибкам (обычно возвращаемое значение -1) добавляются символ ошибки и строка ошибки.

open("/foo/bar", O_RDONLY) = -1 ENOENT (No such file or directory)

Сигналы печатаются как символ сигнала и декодированная структура siginfo. Выдержка из прерывания команды sleep 666:

 sigsuspend([] <unfinished ...>
--- SIGINT {si_signo=SIGINT, si_code=SI_USER, si_pid=...} ---
+++ killed by SIGINT +++

Если выполняется системный вызов, в то время как другой вызов вызывается из другого потока/процесса, то strace попытается сохранить порядок этих событий и пометить текущий вызов как незавершённый. Когда вызов вернется, он будет помечен как возобновлённый.

Прерывание (перезапускаемого) системного вызова доставкой сигнала обрабатывается по-разному, поскольку ядро завершает системный вызов и также организует его немедленное повторное выполнение после завершения обработчика сигнала.

Аргументы печатаются в символической форме. В этом примере показана оболочка, выполняющая перенаправление вывода >>xyzzy:

open("xyzzy", O_WRONLY|O_APPEND|O_CREAT, 0666) = 3

Здесь третий аргумент open декодируется путём разбиения аргумента flag на три составляющие побитового ИЛИ и печати значения режима по традиции в восьмеричном формате. Иногда традиционное или собственное использование отличается от ANSI или POSIX, но эти формы предпочтительнее. В некоторых случаях вывод данных strace оказывается более читабельным, чем исходный.

Указатели на структуру разыменовываются, и элементы соответствующим образом отображаются. В большинстве случаев аргументы форматируются в максимально возможной степени в стиле C. Например, сущность команды ls -l /dev/null записывается как:

lstat("/dev/null", {st_mode=S_IFCHR|0666, st_rdev=makedev(1, 3), ...}) = 0

Следует обратить внимание, как разыменовывается аргумент struct stat и как символически отображается каждый элемент. В частности, как элемент st_mode тщательно декодируется в побитовое ИЛИ символических и числовых значений. Также следует обратить внимание, что в этом примере первый аргумент lstat является входом для системного вызова, а второй аргумент является выходным. Поскольку выходные аргументы не изменяются в случае сбоя системного вызова, аргументы не всегда могут быть разыменованы. Например, повторная попытка примера ls -l с несуществующим файлом приводит к следующей строке.

lstat("/foo/bar", 0xb004) = -1 ENOENT (No such file or directory)

Основные опции

  • -D – запускать процесс трассировки как отдельный "внук", а не как родитель трассировки. Это уменьшает видимый эффект strace, сохраняя трассировку прямым потомком вызывающего процесса.
  • -d – показать некоторые отладочные данные самого strace для стандартной ошибки.
  • -f – отследить дочерние процессы по мере того, как они создаются отслеживаемыми в настоящее время процессами в результате системного вызова fork(2).
  • -q – подавлять сообщения о присоединении, отсоединении и т. д. Это происходит автоматически, когда вывод перенаправляется в файл и команда запускается непосредственно вместо присоединения.
  • -u username – запустить команду с идентификатором пользователя, идентификатором группы и дополнительными группами имени пользователя. Эта опция полезна только при запуске от имени пользователя root и позволяет правильно выполнять двоичные файлы setuid и setgid. Если не используется эта опция, программы setuid и setgid выполняются без действующих привилегий.

Опции выходного формата

  • -a column – выравнивать возвращаемые значения в определённом столбце (по умолчанию 40);
  • -i – распечатать указатель на инструкции во время системного вызова;
  • -k – вывести трассировку стека выполнения отслеживаемых процессов после каждого системного вызова;
  • -o имя_файла – записать вывод трассировки в файл, а не в stderr. Форма filename.pid используется, если указана опция -ff. Если аргумент начинается с '|' или '!', остальная часть аргумента обрабатывается как команда, и весь вывод передается по ней. Это удобно для передачи результатов отладки в программу без влияния на перенаправление исполняемых программ. Последнее не совместимо с опцией -ff в настоящее время.
  • -A – открыть файл, указанный в опции -o, в режиме добавления;
  • -q – подавлять сообщения о присоединении, отсоединении и т. д. Это происходит автоматически, когда вывод перенаправляется в файл и команда запускается непосредственно вместо присоединения.
  • -qq – подавить сообщения о состоянии завершения процесса;
  • -s strsize – указать максимальный размер строки для печати (по умолчанию 32). Следует обратить внимание, что имена файлов не считаются строками и всегда печатаются полностью;
  • -t – префикс каждой строки трассировки со временем настенных часов.

Опции статистики

  • -c – подсчитывать время, вызовы и ошибки для каждого системного вызова и сообщать сводные данные о выходе из программы, подавляя обычный вывод. Команда пытается показать системное время (процессорное время, потраченное на работу в ядре) независимо от времени настенных часов. Если -c используется с -f, сохраняются только совокупные итоги для всех отслеживаемых процессов.
  • -S sortby – сортировать выходные данные гистограммы, напечатанной параметром -c, по указанному критерию. Допустимые значения: time, calls, name и nothing (по умолчанию time).
  • -w – суммировать разницу во времени между началом и концом каждого системного вызова. По умолчанию суммируется системное время.

Опция фильтрации

  • -e expr – уточняющее выражение, которое изменяет, какие события отслеживать или как их отслеживать.

Диагностика

При выходе из команды strace выходит с тем же статусом выхода, что и команда. Если команда завершается сигналом, strace завершает себя тем же сигналом, так что strace может использоваться как процесс-обёртка, прозрачный для вызывающего родительского процесса. Следует обратить внимание, что отношения родитель-потомок (уведомления о прекращении сигнала, значение getppid() и т. д.) между отслеживаемым процессом и его родителем не сохраняются, если не используется -D.

При использовании -p без команды состояние выхода strace равно нулю, если не было присоединено ни одного процесса или произошла непредвиденная ошибка при выполнении трассировки.

Установка Setuid

Если для strace установлен setuid как root, то вызывающий пользователь сможет подключаться и отслеживать процессы, принадлежащие любому пользователю.

Кроме того, программы setuid и setgid будут выполняться и отслеживаться с правильными действующими привилегиями. Эти действия могут быть разрешены только тем пользователям, которым доверены полные права суперпользователя. Поэтому имеет смысл устанавливать strace в качестве setuid для root, когда пользователи, которые могут его выполнять, ограничены теми пользователями, которым доверяют.

Например, имеет смысл установить специальную версию strace с режимом rwsr-xr--, root пользователя и трассировкой группы, где члены группы трассировки являются доверенными пользователями. При использовании этой функции рекомендуется установить не setuid-версию strace для обычных пользователей.

Замечания о работе strace

  • Полезно думать о входах и выходах системного вызова как о потоке данных через границу пространств пользователя/ядра. Поскольку пространство пользователя и пространство ядра являются отдельными и защищёнными адресами, иногда можно сделать дедуктивные выводы о поведении процесса, используя входные и выходные данные в качестве предложений.
  • В некоторых случаях системный вызов будет отличаться от задокументированного поведения или иметь другое имя. Например, в системах, производных от System V, системный вызов time(2) не принимает аргументов, а функция stat называется xstat и принимает дополнительный ведущий аргумент. Эти несоответствия являются нормальными, но уникальными характеристиками интерфейса системных вызовов и учитываются функциями оболочки библиотеки C.
  • На некоторых платформах процесс, к которому применяется системная трассировка вызовов с параметром -p, получит SIGSTOP. Этот сигнал может прервать системный вызов, который не может быть перезапущен. Это может оказать непредсказуемое влияние на процесс, если процесс не предпримет никаких действий для перезапуска системного вызова.

Известные недостатки

  • Программы, использующие бит setuid, не имеют действующих привилегий пользователя с заданным идентификатором ID во время отслеживания.
  • Отслеживаемый процесс игнорирует SIGSTOP, за исключением платформ SVR4.
  • Отслеживаемому процессу, который пытается заблокировать SIGTRAP, будет отправлен SIGSTOP в попытке принудительного продолжения трассировки.
  • Отслеживаемый процесс работает медленно.
  • Отслеживаемые процессы, которые произошли от команды, могут остаться запущенными после сигнала прерывания (CTRL -C).
  • В Linux отслеживание процесса инициализации запрещено.
  • Опция -i слабо поддерживается.

Мы используем cookies для персонализации сайта и его более удобного использования. Вы можете запретить cookies в настройках браузера.

Пожалуйста ознакомьтесь с политикой использования cookies.