strace php позволяет отслеживать системные вызовы при выполнении PHP скриптов. Это основной способ выяснить почему скрипт выполняется не так как ожидается, и единственный способ позволяющий выяснить это не заглядывая в исходный код.
Использование утилиты strace и strace php
Что позволяет делать strace:
- отслеживать системные вызовы
- искать баги в коде без доступа к нему и без знания языка программирования на котором он написан
- понять как работает файловая система — как биты и байты организуются в привычные фйлы
- наблюдать за работой сети уровня TCP/IP
- видеть как процессы работают с памятью
Любая запускаемая программа постоянно выполняет системные вызовы
Основные вызовы:
- open
- read
- write
- connect
- sendto
- recv from
При помощи strace можно отслеживать любой процесс — например, ls, выводящий имена файлов в директории
cd /tmp
strace ls
ioctl(1, TCGETS, {B38400 opost isig icanon echo …}) = 0
ioctl(1, TIOCGWINSZ, {ws_row=43, ws_col=143, ws_xpixel=0, ws_ypixel=0}) = 0
open(«.», O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|O_CLOEXEC) = 3
fstat64(3, {st_mode=S_IFDIR|S_ISVTX|0777, st_size=4096, …}) = 0
getdents64(3, /* 19 entries */, 32768) = 880
getdents64(3, /* 0 entries */, 32768) = 0
close(3) = 0
fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1), …}) = 0
write(1, «config-err-RTW2ya\n», 18config-err-RTW2ya
) = 18
write(1, «e8dbefd7b1cfa6789fdba3ab50168f55"…, 72e8dbefd7b1cfa6789fdba3ab50168f55-{87A94AB0-E370-4cde-98D3-ACC110C5967D}
) = 72
write(1, «firefox_valdemiro\n», 18firefox_valdemiro
) = 18
write(1, «mc-valdemiro\n», 13mc-valdemiro
) = 13
write(1, «systemd-private-3f3a425601f0432c»…, 71systemd-private-3f3a425601f0432c9146511fa7e253e4-colord.service-gHJPz5
) = 71
write(1, «systemd-private-3f3a425601f0432c»…, 77systemd-private-3f3a425601f0432c9146511fa7e253e4-rtkit-daemon.service-KwYCaX
) = 77
write(1, «Temp-d836eecc-8376-4717-9dd3-96d»…, 42Temp-d836eecc-8376-4717-9dd3-96dc876550f3
) = 42
write(1, «unity_support_test.0\n», 21unity_support_test.0
) = 21
close(1) = 0
close(2) = 0
exit_group(0) = ?
+++ exited with 0 +++
Применительно к PHP процессам
Есть три способа отслеживания процессов.
1) — запуская скрипт с интерпретатором
strace php index.php
2) При помощи враппера PHP, создается враппер, благодаря которому все системные вызовы пишутся в лог. Плюс здесь в том, что задействуется CGI, скрипт не выполняется вручную
3) По идентификатору процесса
ps aux | grep php
strace -p PID
PID берется из вывода последней команды
В сети можно найти информацию по любому системному вызову. PHP процессы часто могут обрабатываться медленно из-за того, что ждут ответа от стороннего API, бэкенда или базы данных.
Пример системного вызова (write)
example:
write(1, «unity_support_test.0\n», 21unity_support_test.0
) = 21
1) файловый декскриптор и значение, которое вернулось в результате предыдущего вызова
2) сам системный вызов
3) аргументы
4)количество байт записанной информации
open
open(«/usr/lib/locale/locale-archive», O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 3
open ничего не записывает, 3 в конце = это возвращаемое значение и файловый дескриптор
Что делает процесс можно посмотреть поскольку он является файлом
ls -l /proc/3/fd
Применение strace для дебага
Проверить какие конфигурационные файлы используются
strace -f -e open mplayer musicfile.mp3
Можно запускать утилиту указывая, что нужны только вызовы типа write
strace -e write …
Или вызовы connect, что позволит увидеть IP адреса
strace -e connect …
Вызовы execve при выполнении скрипта script.sh
strace — -e execve ./script.sh
Другие полезные ключи
-f — отслеживать также все порождаемые субпроцессы
-s 800 — ограничивает количество символов в выводе
-o testfile.txt — записывает результаты в файлов
-y — выводит имена файлов вместо файловых дескрипторов
Всегда следует иметь в виду, что strace делает выполнение программ медленнее, поэтому с отслеживанием PHP процессов нагруженных систем лучше проявлять осторожность.
Читайте про управление процессами.