Як слід використовувати стрази?


273

Колись колега сказав мені, що останнім варіантом, коли все не вдалося налагодити в Linux, було використання strace .

Я намагався вивчити науку, що стоїть за цим дивним інструментом, але я не гуру адміністратора системи, і я не отримав результатів.

Так,

  • Що це саме і що робить?
  • Як і в яких випадках його слід використовувати?
  • Як слід розуміти та обробляти результат?

Коротко кажучи простими словами , як працює цей матеріал?


2
strace -p <pid> розповість вам, що зараз відбувається з вашою програмою ..... швидко та просто, ніж GDB
ernesto

1
Мені особисто здається, що це man straceдуже легко читати і корисно. (PS ще не знали про втручання до вчорашнього дня і не експерт Linux)
Олександр Малахов

1
"strace - це відстежувач системних викликів" - він просто показує, які функції ядра викликаються (з їх аргументами) в результаті вашої програми.
Пітікос

Відповіді:


184

Стратегічний огляд страз
можна розглядати як налагоджувач легкої ваги. Це дозволяє програмісту / користувачеві швидко з’ясувати, як програма взаємодіє з ОС. Це робиться шляхом моніторингу системних викликів та сигналів.

Використовується
добре, коли у вас немає вихідного коду або не хочете, щоб вас турбували дійсно пройти через нього.
Також корисно для власного коду, якщо ви не хочете відкривати GDB, а просто зацікавлені в розумінні зовнішньої взаємодії.

Хороший маленький вступ,
я наткнувся на це вступ, щоб напружити використання днями: strace hello world


Що робити, якщо ви використовуєте щось нижче шару, яке напружує монітори?
Pacerier

В цьому випадку перевірка @Pacerier ltrace stackoverflow.com/a/52012215/5884955
PrOSTi

Це чудово для налагодження програм низького рівня, які існують лише / здебільшого для здійснення цікавих системних дзвінків або експериментів з новими параметрами для системних дзвінків, щоб побачити, що робить ваша ОС. В основному це економить проблеми написання журналу / перевірки помилок для разових експериментів. (Або якщо ви пишете в ASM або щось там, де є хороший шанс, що ви випадково передали неправильні аргументи або навіть номер виклику.) Strace набагато швидше, ніж GDB, оскільки він шукає коди errno для вас, наприклад -EFAULT(на жаль, лише для читання буфер) або -ENOENT(упс, вибіг з неправильною директорії , де відносний шлях не зробив роботу)).
Пітер Кордес

62

Простими словами, strace відстежує всі системні дзвінки, видані програмою, разом з їх кодами повернення. Подумайте про такі речі, як операції з файлами / сокетами та багато інших незрозумілих.

Це найкорисніше, якщо ви володієте деякими робочими знаннями C, оскільки тут системні виклики точніше означатимуть стандартні дзвінки з бібліотеки C.

Скажімо, ваша програма / usr / local / bin / кашель. Просто використовуйте:

strace /usr/local/bin/cough <any required argument for cough here>

або

strace -o <out_file> /usr/local/bin/cough <any required argument for cough here>

записати у "out_file".

Весь об'ємний висновок буде спрямований на stderr (будьте обережні, той самий об'єм його часто вимагає перенаправлення на файл). У найпростіших випадках ваша програма перерве помилку, і ви зможете побачити, де відбувається її остання взаємодія з ОС у напруженому виході.

Більше інформації слід отримати:

man strace

36

strace перераховує всі системні дзвінки, здійснені процесом, до якого він застосовується. Якщо ви не знаєте, що означають системні дзвінки, ви не зможете отримати від цього великий пробіг.

Тим не менш, якщо ваша проблема пов'язана з файлами або шляхами або значеннями середовища, запуск пробілу в проблемній програмі і перенаправлення виводу в файл, а потім прив'язування цього файлу до рядка path / file / env може допомогти вам зрозуміти, що насправді намагається програма. зробіть, на відміну від того, що ви цього очікували.


7
А для нетривіальних програм це часто схоже на пиття з пожежного шланга, тому у вас є робота, яка перешкоджає перегляду результатів ...
dmckee --- кошеня колишнього модератора

17
strace <prog_name>простежити програму. strace -o <out_file> <prog_name>викласти в файл
Jestin Joy

8
strace prog 2> & 1 | grep ^ відкрити \ (
eisbaw

10
Або просто: strace -e open myprogАБО для всіх системних дзвінків, пов’язаних із файлами:strace -e file myprog
Amit Naidu

17

Strace виділяється як інструмент для дослідження виробничих систем, де ви не можете дозволити запускати ці програми під налагоджувачем. Зокрема, ми використовували стрази в наступних двох ситуаціях:

  • Програма програми, здається, опинилася в глухому куті і не реагує. Це може бути ціллю для gdb; однак у нас не завжди було вихідного коду або іноді мали справу зі скриптованими мовами, які не були прямими для запуску під налагоджувачем. У цьому випадку ви запускаєте напругу у вже запущеній програмі, і ви отримаєте список системних дзвінків, які здійснюються. Це особливо корисно, якщо ви досліджуєте програму клієнт / сервер або програму, яка взаємодіє з базою даних
  • Дослідження, чому програма повільна. Зокрема, ми щойно перейшли до нової розподіленої файлової системи, і нова пропускна здатність системи була дуже повільною. Ви можете вказати страйк за допомогою параметра '-T', який підкаже, скільки часу було витрачено на кожен системний виклик. Це допомогло визначити, чому файлова система спричиняє сповільнення роботи.

Для прикладу аналізу за допомогою strace дивіться мою відповідь на це питання .


15

Я весь час використовую strace для налагодження проблем з дозволом. Методика виглядає так:

$ strace -e trace=open,stat,read,write gnome-calculator

Де gnome-calculatorкоманда, яку потрібно запустити.


8

strace -tfp PID буде контролювати системні виклики процесу PID, таким чином ми можемо налагоджувати / контролювати стан нашого процесу / програми.


6

Strace можна використовувати як інструмент налагодження, або як примітивний профілер.

Як налагоджувач, ви можете бачити, як задані системні дзвінки викликалися, виконувались і що вони повертають. Це дуже важливо, оскільки дозволяє побачити не тільки те, що програма не вдалася, але ЧОМУ програму не вдалося. Зазвичай це лише результат невдалого кодування, що не дозволяє отримати всі можливі результати програми. В іншому випадку це лише жорсткі коди до файлів. Без напруги ви зможете здогадатися, що пішло не так, де і як. З допомогою strace ви отримуєте зрив системного дзвінка, як правило, просто дивлячись на повернену величину, ви багато говорите.

Профілювання - це ще одне використання. Ви можете використовувати його для виконання часу кожного системного виклику окремо, або як сукупність. Хоча цього може бути недостатньо для вирішення ваших проблем, це принаймні значно звузить список потенційних підозрюваних. Якщо ви бачите багато пар fopen / close пар у одному файлі, ви, ймовірно, непотрібно відкривати та закривати файли при кожному виконанні циклу, замість того, щоб відкривати та закривати його поза циклом.

Лтрас є близьким двоюрідним братом Страсі, також дуже корисним. Ви повинні навчитися розрізняти, де знаходиться вузьке місце. Якщо загальне виконання становить 8 секунд, а ви витрачаєте лише 0,05 сек на системні дзвінки, то розстановка програми не принесе вам багато користі, проблема полягає у вашому коді, який, як правило, є логічною проблемою, або програмі насправді потрібно тривати так довго, щоб бігти.

Найбільшою проблемою з strace / ltrace є читання їх результатів. Якщо ви не знаєте, як здійснюються дзвінки, або принаймні назви системних дзвінків / функцій, розшифрувати значення буде важко. Знання того, що повертаються функції, також може бути дуже корисним, особливо для різних кодів помилок. Хоча це біль розшифрувати, вони іноді дійсно повертають перлину знань; Як тільки я побачив ситуацію, коли мені не вистачало місця, але не було вільного місця, тому всі звичайні утиліти не попереджали мене, я просто не міг створити новий файл. Читання коду помилки з виводу страйсу вказувало мене в правильному напрямку.


4

Strace - це інструмент, який розповідає про взаємодію вашої програми з вашою операційною системою.

Це робиться, повідомляючи про те, яку систему ОС викликає ваша програма і за допомогою яких параметрів вона викликає їх.

Так, наприклад, ви бачите, які файли намагається відкрити програма, і погоджуєтеся, що виклик проходить успішно.

Ви можете налагоджувати всілякі проблеми з цим інструментом. Наприклад, якщо додаток говорить, що він не може знайти бібліотеку, яку ви знаєте, що встановили, що ви встановили, буде вказати, де програма шукає цей файл.

І це лише верхівка айсберга.


це дуже точно.
prosti

4

strace - це хороший інструмент для вивчення того, як ваша програма здійснює різні системні дзвінки (запити до ядра), а також повідомляє про ті, які не відбулися разом зі значенням помилки, пов'язаним з цим збоєм. Не всі невдачі - це помилки. Наприклад, код, який намагається шукати файл, може отримати помилку ENOENT (Немає такого файлу чи каталогу), але це може бути прийнятним сценарієм в логіці коду.

Один хороший випадок використання strace - це налагодження перегонових умов під час створення тимчасових файлів. Наприклад, програма, яка може створювати файли, додаючи ідентифікатор процесу (PID) до якоїсь попередньо визначеної рядки, може зіткнутися з проблемами у багатопотокових сценаріях. [Виправити це буде PID + TID (ідентифікатор процесу + ідентифікатор потоку) або кращий системний виклик, такий як mkstemp].

Це також добре для налагодження збоїв. Ви можете вважати цю (мою) статтю про аварійні втрати та налагодженням налагодження .


4

Приклад мінімальної експлуатації

Якщо концепція не зрозуміла, є більш простий приклад, який ви ще не бачили, що пояснює це.

У цьому випадку, таким прикладом є привітний світ (без libc) збірки Linux x86_64:

привіт.С

.text
.global _start
_start:
    /* write */
    mov $1, %rax    /* syscall number */
    mov $1, %rdi    /* stdout */
    mov $msg, %rsi  /* buffer */
    mov $len, %rdx  /* buffer len */
    syscall

    /* exit */
    mov $60, %rax   /* exit status */
    mov $0, %rdi    /* syscall number */
    syscall
msg:
    .ascii "hello\n"
len = . - msg

GitHub вище за течією .

Зберіть і запустіть:

as -o hello.o hello.S
ld -o hello.out hello.o
./hello.out

Виводить очікувані:

hello

Тепер давайте використаємо стразе на цьому прикладі:

env -i ASDF=qwer strace -o strace.log -s999 -v ./hello.out arg0 arg1
cat strace.log

Ми використовуємо:

strace.log тепер містить:

execve("./hello.out", ["./hello.out", "arg0", "arg1"], ["ASDF=qwer"]) = 0
write(1, "hello\n", 6)                  = 6
exit(0)                                 = ?
+++ exited with 0 +++

Маючи такий мінімальний приклад, кожен окремий символ виводить себе очевидним:

  • execveрядок: показує, як straceвиконується hello.out, включаючи аргументи CLI та середовище, як це зафіксовано вman execve

  • writeрядок: показує виклик системи запису, який ми здійснили. 6- довжина струни "hello\n".

    = 6- це повернене значення системного виклику, яке, як задокументовано, man 2 write- це кількість записаних байтів.

  • exitрядок: показує виклик системи виходу, який ми здійснили. Поверненого значення немає, оскільки програма вийшла з роботи!

Більш складні приклади

Застосування стрази - це, звичайно, щоб побачити, які системні виклики складні програми насправді роблять, щоб допомогти налагодити / оптимізувати вашу програму.

Зокрема, більшість системних дзвінків, з якими ви, швидше за все, зустрічаєтесь в Linux, мають обгортки glibc, багато з яких є POSIX .

Внутрішньо, обгортки glibc використовують вбудовану збірку більш-менш так: Як викликати системний виклик через sysenter під час вбудованого монтажу?

Наступний приклад, який ви повинні вивчити, - це writeсвіт привіт POSIX :

main.c

#define _XOPEN_SOURCE 700
#include <unistd.h>

int main(void) {
    char *msg = "hello\n";
    write(1, msg, 6);
    return 0;
}

Складіть і запустіть:

gcc -std=c99 -Wall -Wextra -pedantic -o main.out main.c
./main.out

Цього разу ви побачите, що glibc здійснює купу системних дзвінків, mainщоб створити гарне середовище для main.

Це тому, що зараз ми не використовуємо окрему програму, а більш звичну програму glibc, яка дозволяє функціонувати libc.

Потім на кожному кінці strace.logміститься:

write(1, "hello\n", 6)                  = 6
exit_group(0)                           = ?
+++ exited with 0 +++

Отже, ми робимо висновок, що writeфункція POSIX використовує, здивуйте !, writeсистемний виклик Linux .

Ми також спостерігаємо, що return 0призводить до exit_groupдзвінка замість exit. Ха, я не знав про це! Ось чому straceтак круто. man exit_groupпотім пояснює:

Цей системний виклик еквівалентний виходу (2), за винятком того, що він завершує не тільки викликовий потік, але й усі потоки в групі потоків процесу виклику.

Ось ще один приклад, де я вивчив, який системний виклик dlopenвикористовує: /unix/226524/what-system-call-is-used-to-load-libraries-in-linux/462710#462710

Тестовано в Ubuntu 16.04, GCC 6.4.0, Linux ядрі 4.4.0.


2

Ось кілька прикладів того, як я використовую strace для копання на веб-сайтах. Сподіваюся, це корисно.

Перевірте час на перший байт так:

time php index.php > timeTrace.txt

Подивіться, який відсоток дій робить що. Багато lstatі fstatможе бути свідченням того, що настав час очистити кеш:

strace -s 200 -c php index.php > traceLstat.txt

Виводить a, trace.txtщоб ви могли точно бачити, які дзвінки здійснюються.

strace -Tt -o Fulltrace.txt php index.php

Використовуйте це , щоб перевірити , чи було що - небудь між .1до .9секунді до навантаження:

cat Fulltrace.txt | grep "[<]0.[1-9]" > traceSlowest.txt

Подивіться, які відсутні файли чи каталоги потрапили в strace. Це виведе багато матеріалів, що стосуються нашої системи - єдині відповідні біти включають файли клієнта:

strace -vv php index.php 2>&1 | sed -n '/= -1/p' > traceFailures.txt

1

Мені сподобалися деякі відповіді, де він читає, straceперевіряє, як ви взаємодієте зі своєю операційною системою.

Це саме те, що ми можемо бачити. Система дзвонить. Якщо порівнювати straceі ltraceрізниця є більш очевидною.

$>strace -c cd
Desktop  Documents  Downloads  examples.desktop  Music  Pictures  Public  Templates  Videos
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
  0.00    0.000000           0         7           read
  0.00    0.000000           0         1           write
  0.00    0.000000           0        11           close
  0.00    0.000000           0        10           fstat
  0.00    0.000000           0        17           mmap
  0.00    0.000000           0        12           mprotect
  0.00    0.000000           0         1           munmap
  0.00    0.000000           0         3           brk
  0.00    0.000000           0         2           rt_sigaction
  0.00    0.000000           0         1           rt_sigprocmask
  0.00    0.000000           0         2           ioctl
  0.00    0.000000           0         8         8 access
  0.00    0.000000           0         1           execve
  0.00    0.000000           0         2           getdents
  0.00    0.000000           0         2         2 statfs
  0.00    0.000000           0         1           arch_prctl
  0.00    0.000000           0         1           set_tid_address
  0.00    0.000000           0         9           openat
  0.00    0.000000           0         1           set_robust_list
  0.00    0.000000           0         1           prlimit64
------ ----------- ----------- --------- --------- ----------------
100.00    0.000000                    93        10 total

З іншого боку, є ltraceте, що відстежує функції.

$>ltrace -c cd
Desktop  Documents  Downloads  examples.desktop  Music  Pictures  Public  Templates  Videos
% time     seconds  usecs/call     calls      function
------ ----------- ----------- --------- --------------------
 15.52    0.004946         329        15 memcpy
 13.34    0.004249          94        45 __ctype_get_mb_cur_max
 12.87    0.004099        2049         2 fclose
 12.12    0.003861          83        46 strlen
 10.96    0.003491         109        32 __errno_location
 10.37    0.003303         117        28 readdir
  8.41    0.002679         133        20 strcoll
  5.62    0.001791         111        16 __overflow
  3.24    0.001032         114         9 fwrite_unlocked
  1.26    0.000400         100         4 __freading
  1.17    0.000372          41         9 getenv
  0.70    0.000222         111         2 fflush
  0.67    0.000214         107         2 __fpending
  0.64    0.000203         101         2 fileno
  0.62    0.000196         196         1 closedir
  0.43    0.000138         138         1 setlocale
  0.36    0.000114         114         1 _setjmp
  0.31    0.000098          98         1 realloc
  0.25    0.000080          80         1 bindtextdomain
  0.21    0.000068          68         1 opendir
  0.19    0.000062          62         1 strrchr
  0.18    0.000056          56         1 isatty
  0.16    0.000051          51         1 ioctl
  0.15    0.000047          47         1 getopt_long
  0.14    0.000045          45         1 textdomain
  0.13    0.000042          42         1 __cxa_atexit
------ ----------- ----------- --------- --------------------
100.00    0.031859                   244 total

Хоча я перевіряв посібники кілька разів, я не знайшов походження назви, straceале це, ймовірно, системний слід виклику, оскільки це очевидно.

Є три більші ноти strace.

Примітка 1: Обидві ці функції straceі ltraceвикористовують системний виклик ptrace. Таким чином, ptraceсистемний виклик ефективно straceпрацює.

Системний виклик ptrace () забезпечує засіб, за допомогою якого один процес ("трекер") може спостерігати та контролювати виконання іншого процесу ("трек"), а також досліджувати та змінювати пам'ять і регістри траєкторії. Він в першу чергу використовується для налагодження точки налагодження та відстеження системних викликів.

Примітка 2: Ви можете користуватися різними параметрами strace, оскільки вони straceможуть бути дуже багатослівними. Мені подобається експериментувати з -cякими, як резюме речей. На основі -cви можете вибрати один системний виклик, наприклад, -e trace=openде ви побачите лише цей виклик. Це може бути цікаво, якщо ви вивчаєте, які файли будуть відкриті під час команди, яку ви відстежуєте. І звичайно, ви можете скористатися цією grepж метою, але зауважте, що вам потрібно перенаправити так, 2>&1 | grep etcщоб зрозуміти, що на конфігураційні файли посилаються при видачі команди.

Примітка 3: Я вважаю цю дуже важливу ноту. Ви не обмежені певною архітектурою. straceпідірве вам розум, оскільки він може простежити бінарні файли різних архітектур. введіть тут опис зображення

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.