Использование strace в Linux

Конспект в доработке

    strace

    Общение программы с внешним миром и операционной системой происходит через набор функций — называемыми системными вызовами.
    Это strace — диагностическая, отладочная и обучающая утилита, используется для мониторинга изменения взаимодействия между процессами и ядром Linux, включая системные вызовы, передачу сигналов и изменения состояния процессов. Работа strace возможна благодаря функции ядра, известной как ptrace ( вызов ptrace(PTRACE_TRACEME) ).
    С помощью системных вызовов можно понять, к каким файлам обращается программа, какие сетевые порты она использует, какие ресурсы ей нужны, а также какие ошибки возвращает ей система
    В простейшем случае strace выполняет указанную команду до тех пор, пока она не завершится.
    Strace перехватывает и записывает системные вызовы, которые вызываются процессом, и сигналы, которые принимаются процессом.
    Системные администраторы, диагносты и специалисты по устранению неполадок найдут его бесценным для решения проблем с программами, исходные тексты которых недоступны
    Сигналы выводятся в виде символа сигнала и декодированной структуры siginfo.
    Если выполняется системный вызов, а в это время другой вызывается из другого потока / процесса, strace попытается сохранить порядок этих событий и пометить текущий вызов как незавершенный (unfinished). Потом он будет помечен как возобновленный.
    В большинстве случаев аргументы форматируются максимально приближенным к C способом.
    В этом примере первый аргумент lstat(2) является входным для системного вызова, а второй аргумент - выходным
    lstat("/dev/null", {st_mode=S_IFCHR|0666, st_rdev=makedev(0x1, 0x3), ...}) = 0
    В примере выше происходит разыменование аргумента 'struct stat' и каждый элемент отображается символически. Элемент st_mode тщательно декодируется в побитовую последовательность символьных и числовых значений.
    Системные вызовы, неизвестные strace, печатаются в необработанном виде, при этом неизвестный номер системного вызова выводится в шестнадцатеричном формате с префиксом "syscall_"
    Пример: syscall_0xbad(0x1, 0x2, 0x3, 0x4, 0x5, 0x6) = -1 ENOSYS (Function not implemented)
    Символьные указатели разыменовываются и печатаются в виде строк на языке Си
    Непечатаемые символы в строках обычно представляются обычными экранирующими кодами языка Си.
    Печатаются только первые строки strsize (по умолчанию 32 байта); к более длинным строкам после заключительной кавычки добавляется многоточие.
    В то время как структуры аннотируются с помощью фигурных скобок, простые указатели и массивы печатаются с помощью квадратных скобок, разделяющих элементы запятыми.
    Пример: getgroups(32, [100, 0]) = 2
    С другой стороны, наборы битов также отображаются в квадратных скобках, но элементы набора разделяются только пробелом.
    Пример: sigprocmask(SIG_BLOCK, [CHLD TTOU], []) = 0
    Здесь второй аргумент представляет собой набор битов из двух сигналов, SIGCHLD и SIGTTOU.
    При необходимости strace может подключиться и к уже запущенному процессу
    Синтаксис: strace опции команда аргументы


    -i - выводить указатель на инструкцию во время выполнения системного вызова;
    -k - выводить стек вызовов для отслеживаемого процесса после каждого системного вызова;
    -o - выводить всю информацию о системных вызовах не в стандартный поток ошибок, а в файл;
    По умолчанию весь вывод strace отправляет в stderr
    Разделить стандартный поток вывода программы и вывод ошибок strace можно при помощи ключа -o, перенаправляющего список системных вызовов в файл-аргумент. Если включена опция --output=filename, трассировка каждого процесса записывается в файл filename.pid, где pid - это числовой идентификатор процесса для каждого процесса.

    strace -e trace=write -owrite-simple.log ls -l #Исключить системный вызов (требуется экранирование знака ! для shell) strace -e trace=\!brk,mmap,mprotect,munmap -owrite-simple.log ls -l


    -q - не выводить сообщения о подключении о отключении от процесса;
    -qq - не выводить сообщения о завершении работы процесса;
    -r - выводить временную метку для каждого системного вызова;
    -s - указать максимальный размер выводимой строки, по умолчанию 32;
    -t - выводить время суток для каждого вызова;
    -tt - добавить микросекунды;
    -ttt - добавить микросекунды и количество секунд после начала эпохи Unix;
    -T - выводить длительность выполнения системного вызова;
    -x - выводить все не ASCI-строки в шестнадцатеричном виде;
    -xx - выводить все строки в шестнадцатеричном виде;
    -y - выводить пути для файловых дескрипторов;
    С флагом -y утилита показывает путь к файлу, которому соответствует дескриптор


    -yy - выводить информацию о протоколе для файловых дескрипторов;
    -c - подсчитывать количество ошибок, вызовов и время выполнения для каждого системного вызова;
    -O - добавить определённое количество микросекунд к счетчику времени для каждого вызова;
    -S - сортировать информацию выводимую при опции -c. Доступны поля time, calls, name и nothing. По умолчанию используется time;
    -w - суммировать время между началом и завершением системного вызова;
    -e - позволяет отфильтровать только нужные системные вызовы или события [qualifier=][!]value[,value]... ;
    Где qualifier это один из: trace (or t), abbrev (or a), verbose (or v), raw (or x), signal (or signals or s), read (or reads or r), write (or writes or w), fault, inject, status, quiet (or silent or silence or q), decode-fds (or decode-fd), decode-pids (or decode-pid), or kvm
    Определителем по умолчанию является trace
    Использование восклицательного знака отменяет набор значений
    Например -e open означает -e trace=open, что означает системный вызов open
    -e trace=!open означает отслеживать каждый системный вызов, за исключением open

    strace -e trace=open,access -o strace.log uname

    -P - отслеживать только системные вызовы, которые касаются указанного пути;
    -v - позволяет выводить дополнительную информацию, такую как версии окружения, статистику и так далее;
    По умолчанию strace не показы вает сами переменные окружения, но его можно попросить выводить более подробную информацию с помощью опции '-v'


    -b - если указанный системный вызов обнаружен, трассировка прекращается;
    --detach-on=syscall
    Если достигнут указанный системный вызов, отключитесь от отслеживаемого процесса
    В настоящее время поддерживается только системный вызов execve

    -f - отслеживать также дочерние процессы, если они будут созданы;
    --follow-forks
    -p PID -f присоединит все потоки процесса PID, если он многопоточный, а не только поток с thread_id = PID

    -ff - если задана опция -o, то для каждого дочернего процесса будет создан отдельный файл с именем имя_файла.pid.
    Это несовместимо с -c, поскольку количество операций для каждого процесса не подсчитывается.

    -I - позволяет блокировать реакцию на нажатия Ctrl+C и Ctrl+Z;
    -E - добавляет переменную окружения для запускаемой программы;
    --env=var=val -добавить или изменить значение переменной
    --env=var - удалить значение переменной

    -p - указывает pid процесса, к которому следует подключиться;
    Можно исползовать что то вроде: -p "$(pidof PROG)"

    -u - запустить программу, от имени указанного пользователя

    Чтобы полноценно пользоваться утилитой strace, нужно ещё разобраться с системными вызовами, которые используются чаще всего
    fork - создание нового дочернего процесса;
    read - попытка читать из файлового дескриптора;
    write - попытка записи в файловый дескриптор;
    open - открыть файл для чтения или записи;
    close - закрыть файл после чтения или записи;
    chdir - изменить текущую директорию;
    execve - выполнить исполняемый файл;
    stat - получить информацию о файле;
    mknod - создать специальный файл, например, файл устройства или сокет;

    Синтаксис системного вызова в выводе: имя_системного_вызова (параметр1, параметр2) = результат сообщение
    Параметры, имена файлов, данные и т.д., передаются в параметрах в скобках, далее идет знак равенства и результат
    Вызов завершается успешно, если строка системного вызова заканчивается нулем или другим положительным числом.
    Системный вызов завершается ошибкой, если строка системного вызова завершается отрицательным числом

    C помощью вызова access проверяются только права на файл или существование самого файла, без каких-либо последующих манипуляций над файлом. Манипуляции над файлом всегда начинаются с системного вызова open, открывающего файл в одном из режимов (O_RDONLY, O_WRONLY или O_RDWR)
    Вызов возвращает небольшое целое число — файловый дескриптор, который впоследствии будет использоваться другими вызовами
    Вызов fstat предназначен для получения информации о файле (номер inode, uid, gid и т.д.)
    uname - вызов, который позволяет получить информацию о текущем ядре
    Источник: https://xakep.ru/2011/01/13/54477


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

    Для подключения к уже запущенной программе достаточно указать номер процесса
    Типичным примером для мониторинга, может быть заблокированный на дескрипторе или спящий процесс

    sudo strace -p 12345
    Фильтрация системных вызовов

    Отсеять ненужный вывод можно с помощью опции -e

    #Выводить только системный вызов clone sudo strace -e trace=clone -p 330797

    Кроме системных вызовов, в качестве параметра для trace можно передавать и такие значения:
    file - все системные вызовы, которые касаются файлов;
    process - управление процессами;
    network - сетевые системные вызовы;
    signal - системные вызовы, что касаются сигналов;
    ipc - системные вызовы IPC;
    desc - управление дескрипторами файлов;
    memory - работа с памятью программы.


    Фильтрация по пути

    Вывод операций связанных с определенным файлом
    Флаг -P с аргументом заставляет strace выводить только обращения к указанному файлу
    В следующем примере видно, что утилита lscpu обращается к файлу /proc/cpuinfo

    #Вывод системных вызовов связанных с указанным файлом sudo strace -P /proc/cpuinfo lscpu sudo strace -P /usr/bin/ls ls
    Статистика системных вызовов
    sudo strace -c ls #Получить информацию в режиме реального времени и вывод результата после завершения ( ctrl + c ) sudo strace -C -p 330797

    time - процент времени от общего времени выполнения системных вызовов;
    seconds - общее количество секунд, затраченное на выполнение системных вызовов этого типа;
    calls - количество обращений к вызову;
    errors - количество ошибок;
    syscall - имя системного вызова.

    Возвращаемые ошибки

    fault=имя_вызова:error=тип_ошибки:when=количество

    #Попросить strace вернуть программе ошибку по нужному системному вызову #например сообщим uname, что системного вызова uname не существует: sudo strace -e fault=uname uname
    Многопоточные программы

    strace может помочь и при работе с многопоточной программой
    Но при сборке программы для линковщика необходимо указывать флаг -pthread

    Диагностика сети

    Иногда strace позволяет решать сетевые проблемы гораздо быстрее, чем tcpdump

    strace -f -e trace=network firefox netbash.ru
    Отследить проблему с тормозами

    Бывает, что какое-то приложение виснет на определенном шаге выполнения, не выдавая никаких ошибок и завершаясь только по kill
    По времени можно увидеть, при выполнении каких системных вызовов приложение задумывается больше допустимого времени

    ldd

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

    ~$ sudo ldd /usr/bin/ls linux-vdso.so.1 (0x00007ffcdc111000) libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007f549da37000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f549d80e000) libpcre2-8.so.0 => /lib/x86_64-linux-gnu/libpcre2-8.so.0 (0x00007f549d777000) /lib64/ld-linux-x86-64.so.2 (0x00007f549daa0000)
    Источники
    Последнее изменение: 21.12.2024 22:34


    Связанные темы
    Здесь пока нет комментариев
    Добавлять комментарии могут только авторизованные пользователи

    Авторизоваться
    Я буду рекламой
    Я тоже буду рекламой
    И я
    ВВЕРХ