Відмінності між версіями «Трасування системних викликів (strace)»
Матеріал з Wiki TNEU
(Створена сторінка: НАЗВА strace - трасує системні виклики та сигнали ЗВЕДЕННЯ strace [ -dffhiqrtttTvxx ] [ -aстовпч...) |
Donserg (Обговорення • внесок) м (Захист на Трасування системних викликів (strace) встановлено ([edit=sysop] (безстроково) [move=sysop] (безстроково))) |
Поточна версія на 23:16, 20 вересня 2012
НАЗВА
strace - трасує системні виклики та сигнали
ЗВЕДЕННЯ
strace [ -dffhiqrtttTvxx ] [ -aстовпчик ] [ -eвираз ] ... [ -oфайл] [ -ppid ] ... [ -sрозмір ] [ -uкористувач ] [ -Eзмінна=значення ] ... [ -Eзмінна ] ... [ команда [ арг ... ] ]
strace -c [ -eвираз ] ... [ -Oнакладка ] [ -Sкритерій ] [ команда [ арг ... ] ]
ОПИС
У найпростішому випадку, strace запускає вказану команду, доки вона не завершить свого виконання. strace перехвачує та занотовує системні виклики, викликані процесом, і сигнали, отримані процесом. Назву кожного системного виклику, його аргументи та значення повернення виводяться на стандартний пристрій помилки, чи записуються до файла, якщо задано прапорець -o.
strace корисна для діагностичних, інструктивних цілей і для відлагодження. Це цінне знаряддя для системних адміністраторів, діагностиків та коректорів, що дозволяє вирішувати проблеми з програмами, чий джерельний код недоступний, оскільки вони не потребують рекомпіляції, щоб трасувати їх. Студенти, гекери та просто цікаві особи можуть багато чого навчитися про систему та системні виклики, трасуючи звичайні програми. А програмісти переконаються, що оскільки системні виклики та сигнали - це події, що відбуваються на межі між користувачем та ядром, ретельне дослідження цієї межі - дуже корисне для виявлення вад, перевірки логіки та виявлення стану перегонів.
Кожний рядок трасування містить назву системного виклику, його аргументи в дужках, і повернене значення. Ось приклад з трасування команди "cat /dev/null":
open("/dev/null", O_RDONLY) = 3
До помилок (типово, повернене значення -1) додається також символічне значення errno разом із ланцюжком опису помилки.
open("/foo/bar", O_RDONLY) = -1 ENOENT (No such file or directory)
Сигнали відображено, як символьні позначення та ланцюжки. Ось приклад трасування та переривання команди "sleep 666":
sigsuspend([] <unfinished ...> --- SIGINT (Interrupt) --- +++ killed by SIGINT +++
Аргументи виводяться в символічній формі з пристрастністю. Наступний приклад демонструє, як оболонка здійснює перенаправлення виводу ">>xyzzy":
open("xyzzy", O_WRONLY|O_APPEND|O_CREAT, 0666) = 3
Тут, трьох-аргументна форма open(2) відображена як назва файла, аргумент прапорців з трьох складових, поєднаних розрядним АБО, і традиційно вісімкове значення режиму. Там де традиційні чи системозалежні форми відрізняються від ANSI чи POSIX, там використовуються форми ANSI або POSIX. Подеколи, вивід strace зрозуміліший ніж джерельний код.
Покажчики на структури розіменовано, а члени відображено належним чином. В усіх випадках, аргументи сформатовано в найбільш C-подібний спосіб. Наприклад, суть команди "ls -l /dev/null" перехоплено як:
lstat("/dev/null", {st_mode=S_IFCHR|0666, st_rdev=makedev(1, 3), ...}) = 0
Зверніть увагу, як розіменовано аргументи "struct stat", і як кожний елемент відображено символічно. Зокрема зауважте, як елемент st_mode дбайливо розшифровано в розрядне АБО символічних і числових значень. Також зауважте в цьому прикладі, що перший аргумент lstat(2) є вводом до системного виклику, а другий аргумент - виводом. Оскільки вивідні аргументи не змінюються, коли виклик зазнав невдачі, то аргументи не завжди будуть розіменовані. Наприклад, та сама спроба команди "ls -l" з файлом, якого не існує, видасть нам наступний рядок:
lstat("/foo/bar", 0xb004) = -1 ENOENT (No such file or directory)
У цьому випадку, світло на ганку ввімкнено, але нікого немає вдома.
Символьні покажчики розіменовуються та виводяться, як ланцюжки C. Недруковні символи в ланцюжках зазвичай виводяться, як звичайні екрановані коди C. Тільки перші strsize (без задання - 32) байтів ланцюжків буде виведено; довші ланцюжки мають трикрапку, додану після закриваючих лапок. Ось приклад "ls -l", де функція бібліотеки getp- wuid(3) читає файл паролей:
read(3, "root::0:0:System Administrator:/"..., 1024) = 422
Якщо структури позначаються фігурними дужками, то прості покажчики та масиви відображено за допомогою квадратних дужок з комами, що розділяють елементи. Ось приклад команди "id" на системі з додатковими ідентифікаційними номерами груп:
getgroups(32, [100, 0]) = 2
З іншого боку, набори бітів також зображено з використанням квадратних дужок, але елементи набору розділено пробілами. Ось приклад оболонки, що готується до виконання зовнішньої команди:
sigprocmask(SIG_BLOCK, [CHLD TTOU], []) = 0
Тут, другий аргумент складається з набору бітів двох сигналів, SIGCHLD і SIGTTOU. Іноді, набори бітів настільки повні, що вивід не ввімкнених елементів - цінніший. У такому разі, перед набором бітів стоїть тильда:
sigprocmask(SIG_UNBLOCK, ~[], NULL) = 0
Тут, другий аргумент представляє повний набір усіх сигналів.
ОПЦІЇ
-c Виводить відлік часу, кількості та помилок кожного системного виклику, і звітує підсумок після закінчення виконання програми.
-d Виводить на стандартний пристрій помилки інформацію відлагодження самої strace.
-f Трасує дочірні процеси, утворені в наслідку виклику fork(2) поточно-трасованим батьківським. Вивід нових процесів буде приєднано, як тільки стане відомо їхній ідентифікаційний номер (завдяки значенню, яке поверне fork(2) батьківському процесові). Це означає, що дочірні процеси можуть виконуватись неконтрольовано деякий час (особливо у випадку vfork(2)), доки батьківський не буде заплановано знову завершити свій виклик (v)fork(2). Якщо батьківський процес вирішить зачекати (функція wait(2)) на дочірній, що трасовано в дану мить, його буде призупинено, доки відповідний дочірній процес або завершиться, або отримає сигнал, що призведе до його завершення (згідно сигнальних настройок дочірнього процесу).
-ff Якщо діє прапорець -o файл, тоді трасування кожного процесу буде збережено у файлі.pid, де pid - це числовий ідентифікаційний номер кожного процесу.
-F Спробувати слідувати за викликами vfork(2). (На SunOS 4.x, це здійснюється завдяки певним хитрощам з динамічним зв'язуванням.) Інакше, vfork() не відстежуватимуться, навіть якщо задано прапорець -f.
-h Виведе поміч по використанню.
-i Виведе покажчик на інструкцію, що відповідає системному викликові.
-q Пригнічує повідомлення про приєднання, від'єднання тощо. Це стається автоматично, коли вивід перенаправлено до файла, і команда запускається безпосередньо, замість бути приєднаною.
-r Виводить відносну часову мітку навпроти кожного системного виклику. Реєструє різницю в часі між успішними системними викликами.
-t Додає попереду кожного рядка трасування час дня.
-tt Якщо вказано двічі, час включатиме мікросекунди.
-ttt Якщо вказано тричі, час включатиме мікросекунди, і передня частина буде відображена, як кількість секунд від початку "епохи".
-T Виводить час, затрачений кожним системним викликом. Реєструє різницю в часі між початком і кінцем виконання кожного системного виклику.
-v Виводить повні версії викликів, пов'язаних з середовищем, статистикою, налагодженням вводу/виводу тощо. Ці структури досить поширені у викликах, тож стандартне поводження - виводити обмежене число членів структур. Скористайтеся з цього прапорця, щоб дізнатися про всі криваві подробиці.
-V Виводить інформацію про версію strace.
-x Виводить ланцюжки, що не належать до набору ASCII, у шістнадцятковому форматі.
-xx Виводить усі ланцюжки у шістнадцятковому форматі.
-c стовпчик Розміщує (вирівнює) повернені значення в певному стовпчику (без задання - в 40-у).
-e вираз Класифікаційний вираз, що змінює те, які події трасувати та як трасувати. Формат виразу наступний:
[класифікатор=][!][значення1[,значення2]...
де класифікатор може бути вказано, як trace, abbrev, verbose, raw, signal, read або write, і значення - це залежний від класифікатора символ чи номер. Стандартним класифікатором є trace. Використання знака оклику заперечує набір значень. Наприклад, -eopen означає буквально -e trace=open, що в свою чергу значить трасувати тільки системні виклики open(). Напротивагу, -etrace=!open означає трасувати всі системні виклики, крім open(). Додатково, спеціальні значення all (все) та none (нічого) мають зрозумілий зміст.
Майте на увазі, що деякі оболонки використовують знак оклику для розкриття історії, навіть всередині залапкованих аргументів. Якщо це так, тоді вам доведеться екранувати знак оклику зворотньою похилою.
-e trace=набір Трасувати тільки вказаний набір системних викликів. Прапорець -c може бути корисним, щоб визначити, які системні виклики здалося б трасувати. Наприклад, trace=open,close,read,write означає трасувати тільки ці чотири системних виклики. Будьте обережні, роблячи висновки про границі "користувач-ядро", коли спостереження ведеться тільки за частиною системних викликів. Стандартним є trace=all.
-e trace=file Трасує всі системні виклики, які мають файл, як аргумент. Це можна вважати скороченням -e trace=open,stat,chmod,unlink,... - зручно, коли треба дізнатися, на які файли посилається процес. Більше того, таке скорочення не дасть вам забути включити якийсь виклик, як скажімо lstat(), до списку. Готовий побитися об заклад, що забули б про нього.
-e trace=process Трасує всі системні виклики, що стосуються керування процесом. Корисно за спостереженням усіх дій fork(), wait() і exec() процесу.
-e trace=network Трасує всі системні виклики, пов'язані з мережею.
-e trace=signal Трасує всі системні виклики, пов'язані з сигналами.
-e trace=ipc Трасує всі системні виклики, пов'язані з IPC (міжпроцесною комунікацією).
-e abbrev=набір Скорочений вивід елементів великих структур для системних викликів з набору. Стандартним є abbrev=all. Прапорець -v тотожний -e abbrev=none.
-e verbose=набір Розіменовує структури для вказаного набору системних викликів. Стандартним є -e verbose=all.
-e raw= набір Виводить необроблені, нерозшифровані аргументи вказаного набору системних викликів. Це спричинить вивід усіх аргументів у шістнадцятковій формі. Корисно переважно тоді, коли ви не довіряєте розшифровуванню, або вам треба знати дійсне числове значення аргументу.
-e signal=набір Трасує тільки вказаний набір сигналів. Стандартним є -e sig‐ nal=all. Так наприклад -e signal=!SIGIO (або -e signal=!io) скасує трасування сигналів SIGIO.
-e read=набір Здійснює повний шістнадцятковий та ASCII дамп усіх даних із файлових дескрипторів, перелічених у наборі. Наприклад, щоб побачити всю діяльність на вводі файлових дескрипторів 3 і 5, скористайтеся з -e read=3,5. Зауважте, що це пов'язано зі звичайним трасуванням системного виклику read(2), контрольованого опцією -e trace=read.
-e write=набір Здійснює повний шістнадцятковий та ASCII дамп усіх даних, записаних до файлових дескрипторів, перелічених у наборі. Наприклад, щоб побачити всю діяльність на виводі файлових дескрипторів 3 і 5, скористайтеся з -e write=3,5. Зауважте, що це пов'язано зі звичайним трасуванням системного виклику write(2), контрольованого опцією -e trace=write.
-o файл Запише вивід трасування до вказаного файла, замість stderr. Використає назву файл.pid (файл та індетифікаційний номер процесу), якщо задано прапорець -ff. Якщо аргумент файл починається з "|" чи "!", тоді решта аргументу вважатиметься командою, і увесь вивід буде передано їй через конвеєр. Зручно для передачі через конвеєр виводу відлагодження програми, не зачіпаючи перенаправлень виконуваної програми.
-O накладка Задає додатковий час на трасування системних викликів, як накладка мікросекунд. Корисно для заміни стандартної евристики відгадування затраченого часу простим виміром часу виконання системних викликів опцією -c. Точність евристики можна настроїти, вимірявши час виконання програми без трасування (з використанням time(1)), і порівнявши акумульований час системних викликів із сумою, поверненою -c.
-p pid Приєднується до процесу з ідентифікаційним номером pid, і починає трасування. Трасування може бути перервано в будь-яку мить клавіатурним сигналом переривання (CTRL-C). У відповідь, strace від'єднає себе від трасованого процесу(ів), залишивши його (їх) для подальшого виконання. Багатократні прапорці -p дозволяють приєднатися аж до 32-ох процесів окрім команди (яка є необов'язковою, якщо заданий принаймні один прапорець -p).
-s розмір_ланцюжка Вказує на максимальний розмір ланцюжка виводу (стандартним є 32). Зауважте, що назви файлів не вважаються звичайними ланцюжками, і завжди виводяться повністю.
-S критерій_сортування Сортує гістограму, виведену прапорцем -c, за вказаним критерієм. Чинними значеннями є time, calls, name та nothing (стандартним є time).
-u користувач Виконає команду з користувацьким ID, ID групи та додаткових груп користувача. Ця опція корисна тільки під час виконання як користувач root, щоб дати можливість правильного виконання бінаріїв із заданим ідентифікаційним номером користувача та/або групи (setuid і/або setgid). Без цього прапорця setuid- та set‐ gid-програми буде виконано без діючих привілеїв.
-E змінна=значення Виконає команду із змінною=значенням в її списку змінних середовища.
-E змінна Видалить змінну з успадкованого списку змінних середовища до того, як передати його команді.