Программа молча завершается с кодом 1
-o пишет трассу в файл, вывод программы остаётся на экране. Последние
отказы перед exited with 1 и есть причина: файл не найден, нет прав,
порт не открылся.
strace показывает системные вызовы программы и их результат: какой файл не открылся, куда не подключилась, на чём висит.
strace cat /etc/hostname
все вызовы команды
strace -f sh -c '…'
и дочерних процессов
strace -e trace=openat cmd
только openat
strace -f -e trace=file cmd
всё, что с путями файлов
strace -e trace=network cmd
сокеты и подключения
strace -o /tmp/t.log -f cmd
в файл, отдельно от вывода
strace -c ls /etc > /dev/null
сводка: сколько каких вызовов
sudo timeout 10 strace -p 1234
подключиться к процессу
Программа сама ничего не открывает и не отправляет: она просит ядро.
Каждая такая просьба — системный вызов: openat
открывает файл, read и write читают и пишут, connect подключается,
exit_group завершает процесс. strace запускает программу и печатает
каждый вызов с аргументами и результатом — в поток ошибок, чтобы не
мешать выводу программы.
имя(аргументы) = результат. openat(…, "/etc/hostname", O_RDONLY) = 3 —
файл открыт и получил дескриптор 3; дальше
read(3, …) читает именно его. write(1, …) пишет в стандартный вывод —
поэтому ubuntu вклинился в строку strace. Последняя строка —
+++ exited with 0 +++, код завершения.
Отказ — результат -1 и имя ошибки:
| Ошибка | Что значит |
|---|---|
ENOENT |
нет такого файла или каталога |
EACCES |
нет прав |
ECONNREFUSED |
на этом порту никто не слушает |
EMFILE |
кончился лимит открытых файлов (см. ulimit) |
EAGAIN |
ресурс занят, попробуй позже |
Не каждый ENOENT — беда. Программа ищет файлы в нескольких местах по
очереди: sh перебрал /usr/local/sbin/ls, /usr/local/bin/ls,
/usr/sbin/ls, прежде чем нашёл /usr/bin/ls. Важен отказ, после которого
программа сдалась — обычно он ближе к концу.
Без -f strace видит только сам запущенный процесс. Оболочка, служба,
скрипт делают работу в потомках — с -f их вызовы видны, у каждой строки
— PID:
Полный вывод — сотни строк. -e trace= оставляет нужные:
| Отбор | Что останется |
|---|---|
-e trace=openat |
только openat |
-e trace=openat,read,write |
перечисленные |
-e trace=file |
всё, где есть путь к файлу: openat, statx, execve, access |
-e trace=network |
socket, connect, sendto, recvfrom |
-e trace=process |
запуск и завершение процессов |
strace -p <PID> подключается к работающему процессу и печатает его вызовы
с этого момента. В Ubuntu kernel.yama.ptrace_scope = 1: без root можно
трассировать только своих потомков. К уже работающему процессу — даже
своему — нужен sudo:
Процесс, который ждёт, показывает незаконченный вызов — без = и
результата. Здесь flock ждёт блокировку, которую держит другой процесс:
timeout 3 отцепляет strace через 3 секунды (код 124); процесс
продолжает работу как ни в чём не бывало. Ctrl+C делает то же.
Основные ключи — в таблице ниже. Полный список — man strace.
| Ключ | Что делает | Пример |
|---|---|---|
-f |
Следовать за дочерними процессами и потоками. | strace -f cmd |
-p PID |
Подключиться к уже работающему процессу по PID. | sudo strace -p 1234 |
-e trace=... |
Фильтр по группе вызовов — file, network, openat,read и другие. | strace -e trace=network cmd |
-c |
Сводка-профиль — какие вызовы и сколько времени они заняли. | strace -c cmd |
-T |
Показать время, потраченное на каждый вызов. | strace -T -e trace=openat cmd |
-y |
Показывать пути и адреса вместо номеров файловых дескрипторов. | strace -y -p 1234 |
-s N |
Длина показываемых строк в выводе (по умолчанию 32 — часто мало). | strace -s 200 -e trace=write -p 1234 |
-o FILE |
Записать вывод в файл вместо терминала. | strace -o trace.log -f cmd |
-tt |
Таймстамп с микросекундами перед каждой строкой. | strace -tt -o trace.log cmd |
Ничего не найдено. Попробуй запрос короче.
-o пишет трассу в файл, вывод программы остаётся на экране. Последние
отказы перед exited with 1 и есть причина: файл не найден, нет прав,
порт не открылся.
root читает любой файл, и под sudo strace отказа в правах не видно.
Служба работает от своего пользователя — от него и трассируй:
Пользователя службы покажет systemctl show -p User <служба>.
Адрес и порт — в аргументах connect.
Одна незаконченная строка — процесс ждёт в этом вызове: flock —
блокировку файла (кто её держит — lsof и /proc/locks, см.
proc-filesystem), read — данных, connect — ответа сети.
Процесс в состоянии D ждёт ядро внутри вызова, и strace может ничего
не напечатать, пока ожидание не кончится (см. load-average).
calls — сколько раз, errors — сколько с отказом, % time — доля
времени в ядре.
ptrace_scope = 1 не даёт подключиться к процессу, который не твой
потомок. Запусти sudo strace -p <PID>. К PID 1 и чужим процессам без
sudo тоже нельзя.
Оба пишут в терминал. -o файл уводит трассу в файл.
strace показывает 32 символа строки, остальное — .... -s 200
показывает 200.
Работу делает дочерний процесс, а strace без -f его не видит.
fd, status, limits процесса в /proc.exited with.EMFILE и лимит открытых файлов.D.Есть неточность? Сообщить об ошибке в статье