Termux стал де-факто стандартом для инженерного анализа на Android: там можно запускать интерпретируемые скрипты, собирать нативные компоненты, вести диагностику сети и устройства. Однако, когда проблема проявляется как «тормозит», «зависает» или «скачет по времени», недостаточно смотреть только логи приложения.
Чтобы понять, где именно теряется время и почему, применяют трассировку системных вызовов и профилирование на уровне ядра. В этом материале разберём практические подходы к strace, bpftrace и perf в среде Termux — для поиска узких мест, чтения/записи, ожиданий, блокировок, системных задержек и «дорогих» участков кода.
Важно об ограничениях Android и Termux
Инструменты уровня системных вызовов и ядра на Android зависят от:
- версии Android и сборки ядра;
- наличия нужных прав (в том числе возможностей доступа к eBPF);
- доступности системных вызовов/трасс-поинтов;
- архитектуры (arm/arm64) и совместимости бинарников.
Поэтому сначала подготовьте окружение и проверьте, что инструмент доступен и запускается. Если ядро/политики не дают доступ к eBPF, bpftrace может быть недоступен или ограничен. Аналогично, perf может требовать дополнительных возможностей.
Подготовка Termux: базовые шаги
Обновите пакеты и установите необходимые утилиты.
pkg update && pkg upgrade -y
pkg install -y strace perf coreutilsДля bpftrace может потребоваться отдельная проверка доступности пакета под вашу сборку Termux и архитектуру. Если он недоступен стандартным способом, сначала уточните совместимость пакета с вашей версией Termux.
pkg install -y bpftraceПроверьте, что команды запускаются и показывают help.
strace -h | head
perf --help | head
bpftrace -h | headstrace: трассировка системных вызовов для диагностики задержек
strace перехватывает и показывает, какие системные вызовы делает процесс, с параметрами и результатами. Это один из самых быстрых способов ответить на вопросы:
- процесс «ждёт» — на каком именно вызове (например, futex, poll, read, recvfrom);
- какие файлы/сокеты активно используются;
- есть ли ретраи, ошибки, повторные попытки открытия;
- есть ли перекос по времени на I/O.
Профилирование уровня «что делает процесс»
Пример трассировки команды целиком:
strace -f -tt -T -o strace.log ./your_binary < input.txtЧто означает:
-f— трассировать дочерние процессы;-tt— абсолютное время;-T— время выполнения каждого системного вызова;-o strace.log— вывод в файл.
Для скриптов (например, Python/Node) strace обычно запускают по процессу интерпретатора или напрямую по вашему исполняемому файлу.
strace -f -tt -T -o strace_python.log python your_script.pyСужение области поиска: фильтры и полезные флаги
strace может быть очень шумным. Для практического анализа удобно смотреть на наиболее вероятные операции:
- сеть:
connect,sendto,recvfrom,poll; - файлы:
openat,read,write,fsync; - ожидания/параллелизм:
futex; - память и динамическая загрузка:
mmap,brk,openat(для библиотек).
Например, чтобы выделить сетевые ожидания:
strace -f -tt -T -e trace=network -o strace_net.log curl -s https://example.comАналогично можно ограничить файловые операции:
strace -f -tt -T -e trace=file -o strace_file.log ./your_binaryПоиск «медленного» системного вызова
После сбора логов полезно быстро найти самые длительные операции по времени -T. Примерно:
grep -E "=[[:space:]]+[0-9]+\.[0-9]+$" strace.log | head -n 50Более корректный способ — скрипт-обработка, но даже быстрый grep помогает понять, что именно «тормозит»: долгие read/recvfrom, задержки в poll, серия openat или неожиданные fsync.
Когда strace особенно полезен
- нужно быстро понять, почему приложение «зависает» — какой системный вызов блокирует поток;
- есть подозрение на проблемную I/O-логику (много маленьких чтений/записей, лишние flush/синхронизации);
- есть сетевые таймауты/ретраи;
- нужно сравнить две версии приложения или разные режимы выполнения.
bpftrace: трассировка событий ядра для углублённого анализа
bpftrace позволяет собирать данные на уровне ядра через eBPF-технологии. Это открывает более широкий горизонт, чем strace: можно наблюдать частоту и длительность событий, системные задержки и поведение планировщика/драйверов без постоянной прокрутки подробных трасс.
Сценарии, где bpftrace часто даёт выигрыш:
- наблюдение распределения времени выполнения операций ввода/вывода;
- оценка задержек планировщика, wakeup/switch паттернов;
- детальная картина по «как часто и где» происходят события (вместо полного логирования каждого системного вызова).
Проверка доступности bpftrace
Простейший тест — запустить bpftrace и убедиться, что скрипты выполняются без ошибок. Пример «в воздухе» (конкретные пробники зависят от ядра):
bpftrace -e 'BEGIN { printf("bpftrace works
"); }'Если получите ошибки доступа к eBPF, это означает ограничение со стороны ядра/политик. В таком случае переходите на strace/perf и/или используйте более доступные источники данных.
Практические шаблоны bpftrace (общий подход)
Точные пробники (probe points) зависят от ядра и поддерживаемых событий. В работе важно придерживаться следующего процесса:
- Выбрать область: I/O, сеть, планировщик, блокировки.
- Запустить короткий сбор данных с фильтром по PID (если известен).
- Убедиться, что количество событий разумное (иначе лог будет огромным).
- Собрать метрики: частоты, длительности, распределения.
- Повторить для сравнения (например, «до оптимизации» vs «после»).
Если bpftrace доступен, вы сможете строить такие наблюдения более «метрически», а не построчно, как strace.
perf: профилирование производительности и «горячих» участков
perf — это инструмент профилирования (часто sample-based) для нахождения горячих функций, потерь времени в CPU, а также причин роста задержек.
В контексте Termux perf помогает:
- понять, какие функции/модули грузят процессор;
- сравнить разные режимы выполнения;
- увидеть влияние нативных библиотек;
- оценить эффекты оптимизаций компилятора/кода.
Сбор профиля для нативной программы
Пример базового профилирования с указанием времени:
perf record -F 99 -g -- ./your_binary < input.txtС флагами можно экспериментировать под вашу задачу. Затем отобразите результаты:
perf report --stdio | head -n 80Если нужно сохранять отчёт:
perf report -i perf.data --stdio > perf_report.txtСбор статистики без развёрнутого отчёта
Иногда достаточно быстрых метрик:
perf stat -- ./your_binary < input.txtВажно: результаты perf зависят от поддержки аппаратных счётчиков и конфигурации ядра Android. Если perf сообщает об ограничениях — это означает, что часть функциональности не доступна в вашей среде, и придётся опираться на альтернативные методы (strace и наблюдения по времени системных вызовов).
Комбинирование подходов: эффективный workflow
На практике лучший эффект даёт связка:
- strace — отвечает «что блокирует/ждёт» и на каких системных вызовах тратится время;
- perf — отвечает «где в CPU/коде тратятся циклы» (горячие функции);
- bpftrace — даёт «метрическую картину» на уровне ядра, если eBPF доступен.
Типовой сценарий расследования
Запустите процесс в наблюдаемом режиме и снимите perf stat или perf record, чтобы понять характер нагрузки (CPU vs ожидания).
Если видно ожидание/низкая загрузка CPU — снимите strace -T и найдите медленные системные вызовы (например,
poll/recvfrom/futex/read).Если нужен более широкий «почему так часто» на уровне ядра — попробуйте bpftrace (при наличии доступа) для метрик по событиям.
Сравните два запуска: до/после изменения. Фиксируйте параметры, входные данные и окружение.
Примеры команд для сравнения режимов
Профилирование с фиксацией вывода:
perf stat -o perf_stat_v1.txt -- ./your_binary < input.txt
perf stat -o perf_stat_v2.txt -- ./your_binary < input.txtstrace на два варианта:
strace -f -tt -T -o strace_v1.log ./your_binary < input.txt
strace -f -tt -T -o strace_v2.log ./your_binary < input.txtДалее сравнивайте длительные системные вызовы и структуру запросов/операций.
Советы по интерпретации результатов
Если «долгие» системные вызовы — это I/O, оптимизируйте число операций (буферизация), паттерны чтения/записи, избегайте лишних flush/fsync.
Если «долгие» — это ожидания (poll/recvfrom/futex), проверьте таймауты, конкурентность, порядок блокировок, размер очередей.
Если perf показывает горячие функции в пользовательском коде, сосредоточьтесь на оптимизации алгоритма, inlining, уменьшении аллокаций, векторизации/эффективных структурах.
Не делайте выводы по одному прогону: Android может влиять фон, термальные ограничения и планировщик.
О локальной сети для удалённого анализа (если требуется)
Если вам нужно получать данные/логировать результаты на другой компьютер в ходе диагностики, можно настроить локальную сеть (например, через VPN в режиме создания локального соединения) и передавать файлы отчётов. Это не используется для обхода блокировок — только для удобства сбора и хранения результатов.
Заключение
Мониторинг и трассировка в Termux — это практичный путь от симптома «тормозит» к конкретной причине: где процесс ждёт, какие системные вызовы «съедают» время, и какие участки кода создают нагрузку. strace помогает увидеть точные блокирующие точки на уровне системных вызовов, perf выявляет горячие функции и характер вычислительных затрат, а bpftrace (при доступности eBPF) позволяет собрать метрики событий ядра для более глубокого анализа.
Если вам нужен разбор конкретного кейса (скрипт, сервис, нативная утилита), настройка инструментов под вашу сборку Android и подготовка профилей/логов для сравнения версий — обращайтесь в РыбинскЛАБ. Мы поможем организовать диагностику, интерпретировать результаты и предложить обоснованные оптимизации.