Что такое strace и как отлаживать системные вызовы

8 минут чтения
Средний рейтинг статьи — 4.7

strace — это мощный инструмент для отслеживания системных вызовов и сигналов, совершаемых процессами в Linux. Он позволяет разработчикам и администраторам смотреть "под капот" исполняемых программ и понять, как именно они взаимодействуют с ядром.

Этот инструмент особенно полезен, когда:

  • программа "висит" без объяснения причин;
  • происходят ошибки ввода-вывода;
  • неясно, какие файлы или сокеты открывает процесс;
  • нужно понять поведение стороннего бинарника без исходников.

Как работает strace?

strace использует системный механизм ptrace, который позволяет одному процессу "подглядывать" за другим. При запуске strace перехватывает все системные вызовы процесса и выводит их в читаемом виде в консоль или файл.

Установка strace

На большинстве дистрибутивов Linux strace можно установить через менеджер пакетов:

sudo apt install strace     # для Debian/Ubuntu
sudo yum install strace     # для CentOS/RHEL
sudo pacman -S strace       # для Arch Linux

Базовое использование

Чтобы просто посмотреть системные вызовы при запуске команды:

strace ls

Вывод будет содержать строки вроде:

openat(AT_FDCWD, ".", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 3
getdents64(3, /* 18 entries */, 32768) = 496

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

Запуск с трассировкой уже работающего процесса

Можно подключиться к уже запущенному процессу по PID:

sudo strace -p 1234

Для удобства можно указать -f, чтобы отслеживать и дочерние процессы:

sudo strace -fp 1234

Вывод в файл

Чтобы не засорять терминал:

strace -o output.txt some_command

Фильтрация по типу системных вызовов

Если вас интересуют только операции с файлами:

strace -e trace=file some_command

Поддерживаются категории: file, network, process, signal, ipc и др.

Поиск ошибок

Очень удобно использовать strace для выявления ошибок вроде ENOENT (файл не найден):

strace some_command 2>&1 | grep ENOENT

Практические примеры

Узнать, какие конфиги загружает приложение:

strace -e openat your_app 2>&1 | grep '\.conf'

Проверка доступа к сети:

strace -e trace=network curl https://example.com

Подключение к запущенному демону:

ps aux | grep nginx
sudo strace -fp <pid_nginx>

Получение информации о времени выполнения

strace позволяет получать информацию о времени и продолжительности системных вызовов.

Временная метка каждого вызова

Флаг -t добавляет к каждому системному вызову временную метку:

$ strace -t whoami
06:02:38 execve("/usr/bin/whoami", ["whoami"], 0x7ffdc4811038 /* 12 vars */) = 0

Временная метка с точностью до микросекунд

Флаг -tt отображает временную метку с точностью до микросекунд:

$ strace -tt whoami
06:07:10.899089 execve("/usr/bin/whoami", ["whoami"], 0x7fff396d2898 /* 12 vars */) = 0

Продолжительность выполнения каждого вызова

Флаг -T показывает, сколько времени занял каждый системный вызов:

$ strace -T whoami
execve("/usr/bin/whoami", ["whoami"], 0x7fff0493d078 /* 12 vars */) = 0 <0.000274>

Значение в угловых скобках указывает, сколько секунд было затрачено на выполнение конкретного системного вызова. В данном примере вызов execve занял 0.000274 секунды.

Отчет со статистикой

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

Краткий отчет о запуске команды

Флаг -c позволяет получить сводку вместо показа всех вызовов:

$ strace -c whoami

Пример вывода:

% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 18.62    0.000264          26        10           close
 15.16    0.000215          16        13           mmap
 12.27    0.000174          29         6           openat
...
  0.00    0.000000           0         1         1 access
  0.00    0.000000           0         1           execve
  0.00    0.000000           0         2         1 arch_prctl
------ ----------- ----------- --------- --------- ----------------
100.00    0.001418                    68         4 total

Каждая строка показывает:

  • % time — процент времени, затраченного на данный системный вызов
  • seconds — абсолютное время в секундах
  • usecs/call — среднее время одного вызова в микросекундах
  • calls — количество вызовов
  • errors — количество ошибок

Совмещение сводки и обычного вывода

Флаг -C позволяет одновременно увидеть как обычный вывод strace, так и итоговую сводку:

$ strace -C whoami

Сортировка вывода по разным столбцам

С помощью флага -S можно отсортировать результат сводки. Например, чтобы отсортировать по количеству ошибок:

$ strace -c -S errors whoami

Результат будет выведен по убыванию количества ошибок на каждый системный вызов.

Советы по использованию

  • Используйте less или grep для анализа большого вывода
  • Не запускайте strace без нужды на продакшене — он может заметно замедлить процесс
  • Отлично работает в сочетании с другими инструментами вроде lsof, tcpdump, gdb

Заключение

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

8 минут чтения
Средний рейтинг статьи — 4.7

Настроить мониторинг за 30 секунд

Надежные оповещения о даунтаймах. Без ложных срабатываний