Linux trace system calls

Содержание
  1. How to Trace Program Execution Using Linux Strace Command
  2. Install Strace
  3. 1. Trace a System Calls
  4. 2. Filter Specific System Calls
  5. 3. Attach to Already Running Process
  6. 4. Redirect Trace Output to a File
  7. 5. Print Time Spent on System Calls
  8. 6. Display Instruction Pointer of System Call
  9. 7. Generate a System Call Report
  10. 8. Print Debugging Output of strace
  11. 9. Trace System Calls Based on a Certain Condition
  12. Conclusion
  13. 10 Strace Commands for Troubleshooting and Debugging Linux Processes
  14. How to Install Strace Process Monitoring Tool in Linux
  15. 1. Trace Linux Command System Calls
  16. 2. Trace Linux Process PID
  17. 3. Get Summary of Linux Process
  18. 4. Print Instruction Pointer During System Call
  19. 5. Show Time of Day For Each Trace Output Line
  20. 6. Print Command Time Spent in System Calls
  21. 7. Trace Only Specific System Calls
  22. 8. Trace System Calls Based on a Certain Condition
  23. 9. Redirect Trace Output to File
  24. 10. Show Some Debugging Output of Strace
  25. If You Appreciate What We Do Here On TecMint, You Should Consider:
  26. Strace в Linux: история, устройство и использование
  27. Содержание
  28. Происхождение видов
  29. Устройство strace в двух словах: Piglet Trace
  30. Азы: запуск программы под управлением strace
  31. Азы: присоединение к процессу на лету
  32. Пример: отслеживание дочерних процессов
  33. Пример: пути к файлам вместо дескрипторов
  34. Пример: отслеживание обращений к файлам
  35. Пример: многопоточные программы
  36. Мастер-класс: стек процесса в момент системного вызова
  37. Мастер-класс: инъекция ошибок
  38. Послесловие

How to Trace Program Execution Using Linux Strace Command

The strace is a powerful command-line tool for process monitoring, diagnostic and troubleshooting programs in Linux. Generally, it is used to intercept and record the system calls and the signals received by a process. You can use strace to analyze how a program interacts with the system to debug any program.

This tool is very useful if the program continually crashes, or does not behave as expected. It provides deep insight into how the system operates. Any user may trace their own running processes.

In this tutorial, we will show you how to use the strace command-line tool on Linux.

Install Strace

By default, strace is available in the default repository of all Linux operating systems.

On Debian and Ubuntu operating systems, install the strace with the following command:

On RHEL and CentOS operating systems, install the strace with the following command:

After installing strace, you can verify the strace version using the following command:

You should get the following output:

You can print all options available with strace command with the following command:

1. Trace a System Calls

If you want to trace the system calls of the command ls, run the following command:

In the above output, you can see the system call and result of the call of ls command. You should also see that exit status is 0. That means there was no error.

One use of strace (Except debugging some problem) is that you can find out which configuration files are read by a program.

2. Filter Specific System Calls

Be default, strace displays all system calls for the given executable. If you want to display only a specific system call, you can use strace -e option.

For example, to displays only the write system call of the ls command run the following command:

To displays only the open system call of the ls command run the following command:

If you want to display files opened by a specific process like SSH, run the following command:

To trace network-related system calls, run the following command:

3. Attach to Already Running Process

If a process is already running, you can trace it using its PID as shown below:

This command will continuously showing system calls made by the process. You can press CTRL+C to stop it.

5315 is a process ID of the running process.

4. Redirect Trace Output to a File

You can use -o flag with strace command to save the strace output to specified file.

You can now display the content of the file file_out.txt with the following command:

5. Print Time Spent on System Calls

To print the relative timestamp of each call, use the -r flag as shown below.

To display the time difference between the starting and the end of each system call made by ls command, use the -T option.

To print the wall clock time of each system call, run the following command:

The -tt option displays timestamp followed by microsecond.

6. Display Instruction Pointer of System Call

You can use -i flag with strace command to print the instruction pointer at the time of each system call made by the command:

7. Generate a System Call Report

You can use the -c flag to get the useful statistical report for the execution trace.

In the above output, the «calls» column indicated how many times that particular system call was executed.

8. Print Debugging Output of strace

To print debugging information for strace command, use -d flag as shown below:

9. Trace System Calls Based on a Certain Condition

You can also trace the system calls based on the specific condition. For example, trace all the system calls related to memory management run the following command:

Читайте также:  Установка линукс manjaro рядом с виндовс 10

To trace the signal realted system calls, run the following command:

To trace the process realted system calls, run the following command:

Conclusion

In the above guide, you learned how to use the strace command with several examples. This tool is very useful for system administrators and programmers to debug and troubleshoot any program.

Источник

10 Strace Commands for Troubleshooting and Debugging Linux Processes

strace is a powerful command line tool for debugging and trouble shooting programs in Unix-like operating systems such as Linux. It captures and records all system calls made by a process and the signals received by the process.

It displays the name of each system call together with its arguments enclosed in a parenthesis and its return value to standard error; you can optionally redirect it to a file as well.

In this article, we will explain 10 strace command examples for troubleshooting and debugging programs and processes in a Linux system.

How to Install Strace Process Monitoring Tool in Linux

If strace is not pre-installed on your Linux system, run the appropriate command below for your distribution, to install it.

In case a program crashes or behaves in a way not expected, you can go through its systems calls to get a clue of what exactly happened during its execution. As we will see later on, system calls can be categorized under different events: those relating to process management, those that take a file as an argument, those that involve networking, memory mapping, signals, IPC and also file descriptor related system calls.

You can either run a program/command with strace or pass a PID to it using the -p option as in the following examples.

1. Trace Linux Command System Calls

You can simply run a command with strace like this, here we are tracing of all system calls made by the df command.

>P\t». 832) = 832 fstat(3, ) = 0 mmap(NULL, 3971488, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f82f7310000 .

From the output above, you can see various types of system calls made by df command, for example.

  • open – is the type of system call
  • (“/etc/ld.so.cache”, O_RDONLY|O_CLOEXEC) – system call argument
  • 3 – system call return value

Below is an sample output showing the write system calls, that displays df command output on the screen.

2. Trace Linux Process PID

If a process is already running, you can trace it by simply passing its PID as follows; this will fill your screen with continues output that shows system calls being made by the process, to end it, press [Ctrl + C] .

%», 4096>], msg_controllen=0, msg_flags=0>, 0) = 32 recvmsg(4, 0x7ffee4dbf870, 0) = -1 EAGAIN (Resource temporarily unavailable) recvmsg(4, 0x7ffee4dbf850, 0) = -1 EAGAIN (Resource temporarily unavailable) poll([, , , , , ], 6, -1) = 1 ([]) read(31, «2», 1) = 1 recvmsg(4, 0x7ffee4dbf850, 0) = -1 EAGAIN (Resource temporarily unavailable) poll([, , , , , ], 6, 0) = 1 ([]) read(31, «2», 1) = 1 recvmsg(4, 0x7ffee4dbf850, 0) = -1 EAGAIN (Resource temporarily unavailable) poll([, , , , , ], 6, 0) = 0 (Timeout) mprotect(0x207faa20000, 8192, PROT_READ|PROT_WRITE) = 0 mprotect(0x207faa20000, 8192, PROT_READ|PROT_EXEC) = 0 mprotect(0x207faa21000, 4096, PROT_READ|PROT_WRITE) = 0 mprotect(0x207faa21000, 4096, PROT_READ|PROT_EXEC) = 0 .

3. Get Summary of Linux Process

Using the -c flag, you can generate a report of total time, calls, and errors for each system call, as follows.

4. Print Instruction Pointer During System Call

The -i option displays the instruction pointer at the time of each system call made by the program.

>P\t». 832) = 832 [00007faf9cafb2b4] fstat(3, ) = 0 [00007faf9cafb47a] mmap(NULL, 3971488, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7faf9c716000 [00007faf9cafb517] mprotect(0x7faf9c8d6000, 2097152, PROT_NONE) = 0 .

5. Show Time of Day For Each Trace Output Line

You can also print the time of day for each line in the trace output, by passing the -t flag.

>P\t». 832) = 832 15:19:25 fstat(3, ) = 0 15:19:25 mmap(NULL, 3971488, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f8c7ebec000 15:19:25 mprotect(0x7f8c7edac000, 2097152, PROT_NONE) = 0 .

6. Print Command Time Spent in System Calls

To shows the time difference between the starting and the end of each system call made by a program, use the -T option.

7. Trace Only Specific System Calls

In the command below, trace=write is known as a qualifying expression, where trace is a qualifier (others include signal, abbrev, verbose, raw, read, or write). Here, write is the value of the qualifier.

The following command actually shows the system calls to print df output on standard output.

Here are some additional commands about trace qualifier.

8. Trace System Calls Based on a Certain Condition

Let’s look at how to trace system calls relating to a given class of events. This command can be used to trace all system calls involving process management.

Next, to trace all system calls that take a filename as an argument, run this command.

To trace all system calls involving memory mapping, type.

You can trace all network and signals related system calls.

9. Redirect Trace Output to File

To write the trace messages sent to standard error to a file, use the -o option. This means that only the command output is printed on the screen as shown below.

To look through the file, use cat command.

10. Show Some Debugging Output of Strace

To show debugging information for strace tool, use the -d flag.

Читайте также:  Как открыть командную строку если windows не загружается

For additional information, see the strace man page.

Also read these useful related articles:

In conclusion, strace is a remarkable tool for diagnosing cause(s) of program failure: it is a powerful debugging and trouble shooting. It is practically useful to experienced system administrators, programmers and hackers. To share any thoughts concerning this article, use the feedback form below.

If You Appreciate What We Do Here On TecMint, You Should Consider:

TecMint is the fastest growing and most trusted community site for any kind of Linux Articles, Guides and Books on the web. Millions of people visit TecMint! to search or browse the thousands of published articles available FREELY to all.

If you like what you are reading, please consider buying us a coffee ( or 2 ) as a token of appreciation.

We are thankful for your never ending support.

Источник

Strace в Linux: история, устройство и использование

В Unix-подобных операционных системах общение программы с внешним миром и операционной системой происходит через небольшой набор функций — системных вызовов. А значит, в отладочных целях полезно бывает подсмотреть за выполняемыми процессами системными вызовами.

Следить за «интимной жизнью» программ на Linux помогает утилита strace , которой и посвящена эта статья. К примерам использования «шпионского» оборудования прилагаются краткая история strace и описание устройства подобных программ.

Содержание

Происхождение видов

Главный интерфейс между программами и ядром OC в Unix — системные вызовы (англ. system calls, syscalls), взаимодействие программ с внешним миром происходит исключительно через них.

Но в первой публичной версии Unix (Version 6 Unix, 1975 год) удобных способов отслеживания поведения пользовательских процессов не было. Для решения этой проблемы Bell Labs к следующей версии (Version 7 Unix, 1979 год) предложили новый системный вызов — ptrace .

Разрабатывался ptrace прежде всего для интерактивных отладчиков, но к концу 80-х (в эпоху коммерческого уже System V Release 4) на этой основе появились и получили широчайшее распространение узконаправленные отладчики — трассировщики системных вызовов.

Первая же версия strace была опубликована Полом Кроненбургом в рассылке comp.sources.sun в 1992 году в качестве альтернативы закрытой утилите trace от Sun. Как клон, так и оригинал предназначались для SunOS, но к 1994 году strace была портирована на System V, Solaris и набирающий популярность Linux.

Сегодня strace поддерживает только Linux и опирается на всё тот же ptrace , обросший множеством расширений.

Современный (и весьма активный) мейнтейнер strace — Дмитрий Левин. Благодаря ему утилита обзавелась продвинутыми возможностями вроде инъекции ошибок в системные вызовы, поддержкой широкого спектра архитектур и, главное, маскотом. Неофициальные источники утверждают, что выбор пал на страуса из-за созвучности русского слова «страус» и английского «strace».

Немаловажно и то, что системный вызов ptrace и трассировщики так и не были включены в POSIX, несмотря на долгую историю и наличие реализации в Linux, FreeBSD, OpenBSD и традиционных Unix.

Устройство strace в двух словах: Piglet Trace

«You are not expected to understand this» (Деннис Ричи, комментарий в исходном коде Version 6 Unix)

С раннего детства я терпеть не могу чёрные ящики: с игрушками я не играл, а пытался разобраться в их устройстве (взрослые употребляли слово «ломал», но не верьте злым языкам). Возможно, поэтому мне так близки неформальная культура первых Unix и современного open-source-движения.

В рамках этой статьи разбирать исходный код раздобревшей за десятилетия strace неразумно. Но и тайн для читателей оставаться не должно. Поэтому, чтобы показать принцип работы подобных strace программ, я приведу код миниатюрного трассировщика — Piglet Trace (ptr). Ничего особенного он делать не умеет, но главное — системные вызовы программы — выводит:

Piglet Trace распознает порядка сотни системных вызовов Linux (см. таблицу) и работает только на архитектуре x86-64. Для учебных целей этого достаточно.

Давайте разберём работу нашего клона. В случае с Linux для отладчиков и трассировщиков используется, как упоминалось выше, системный вызов ptrace. Он работает посредством передачи в первом аргументе идентификаторов команд, из которых нам нужны только PTRACE_TRACEME , PTRACE_SYSCALL и PTRACE_GETREGS .

Работа трассировщика начинается в обычном Unix-стиле: fork(2) запускает дочерний процесс, а тот в свою очередь с помощью exec(3) запускает исследуемую программу. Единственная тонкость здесь — вызов ptrace(PTRACE_TRACEME) перед exec : процесс-потомок ожидает, что процесс-родитель будет его отслеживать:

Процесс-родитель теперь должен вызвать wait(2) в дочернем процессе, то есть убедиться, что переключение в режим трассировки произошло:

На этом приготовления закончены и можно приступать непосредственно к отслеживанию системных вызовов в бесконечном цикле.

Вызов ptrace(PTRACE_SYSCALL) гарантирует, что последующий wait родителя завершится либо перед исполнением системного вызова, либо сразу после его завершения. Между двумя вызовами можно осуществить какие-либо действия: заменить вызов на альтернативный, изменить аргументы или возвращаемое значение.

Нам же достаточно дважды вызвать команду ptrace(PTRACE_GETREGS) , чтобы получить состояние регистра rax до вызова (номер системного вызова) и сразу после (возвращаемое значение).

Вот и весь трассировщик. Теперь вы знаете, с чего начинать очередное портирование DTrace на Linux.

Азы: запуск программы под управлением strace

В качестве первого примера использования strace , пожалуй, стоит привести самый простой способ — запуск приложения под управлением strace .

Чтобы не копаться в бесконечном списке вызовов типичной программы, напишем минимальную программу вокруг write :

Соберем программу и убедимся, что она работает:

И наконец запустим ее под управлением strace:

Очень «многословно» и не очень познавательно. Проблемы здесь две: вывод программы смешан с выводом strace и изобилие системных вызовов, которые нас не интересуют.

Читайте также:  Metal doors and windows

Разделить стандартный поток вывода программы и вывод ошибок strace можно при помощи ключа -o, перенаправляющего список системных вызовов в файл-аргумент.

Осталось разобраться с проблемой «лишних» вызовов. Предположим, что нас интересуют только вызовы write . Ключ -e позволяет указывать выражения, по которым будут фильтроваться системные вызовы. Самый популярный вариант условия — естественно, trace=* , при помощи которого можно оставить только интересующие нас вызовы.

При одновременном использовании -o и -e мы получим:

Так, согласитесь, намного проще читается.

А ещё можно убирать системные вызовы — например, связанные с выделением и освобождением памяти:

Обратите внимание на экранированный восклицательный знак в списке исключённых вызовов: этого требует командная оболочка (англ. shell).

В моей версии glibc завершает исполнение процесса системный вызов exit_group , а не традиционный _exit . В этом состоит сложность работы с системными вызовами: интерфейс, с которым работает программист, не имеет прямого отношения к системным вызовам. Более того, он регулярно меняется в зависимости от реализации и платформы.

Азы: присоединение к процессу на лету

Изначально системный вызов ptrace, на котором построена strace , можно было использовать только при запуске программы в специальном режиме. Такое ограничение, быть может, звучало разумно во времена Version 6 Unix. В наши же дни этого уже недостаточно: бывает, нужно исследовать проблемы работающей программы. Типичный пример — заблокированный на дескрипторе или спящий процесс. Поэтому современная strace умеет присоединяться к процессам на лету.

Соберём программу и убедимся в том, что она зависла:

А теперь попробуем присоединиться к ней:

Программа заблокирована вызовом pause . Посмотрим, как она отреагирует на сигналы:

Мы запустили зависнувшую программу и присоединились к ней при помощи strace . Выяснились две вещи: системный вызов pause игнорирует сигналы без обработчиков и, что интереснее, strace отслеживает не только системные вызовы, но и входящие сигналы.

Пример: отслеживание дочерних процессов

Работа с процессами через вызов fork — основа всех Unix. Давайте посмотрим, как strace работает с деревом процессов на примере несложной «плодящейся» программы:

Здесь исходный процесс создаёт дочерний процесс, оба пишут в стандартный поток вывода:

По умолчанию мы увидим только системные вызовы родительского процесса:

Отслеживать дерево процессов целиком помогает флаг -f , с которым strace отслеживает системные вызовы в процессах-потомках. К каждой строке вывода при этом добавляется pid процесса, делающего системный вывод:

В этом контексте может пригодиться фильтрация по группам системных вызовов:

Кстати, какой системный вызов используется для создания нового процесса?

Пример: пути к файлам вместо дескрипторов

Знать файловые дескрипторы, безусловно, полезно, но имена конкретных файлов, к которым обращается программа, тоже могут пригодиться.

Следующая программа пишет строку во временный файл:

При обычном вызове strace покажет значение числа-дескриптора, переданного в системный вызов:

С флагом -y утилита показывает путь к файлу, которому соответствует дескриптор:

Пример: отслеживание обращений к файлам

Ещё одна полезная возможность: отображать только системные вызовы, связанные с конкретным файлом. Следующая программа дописывает строку в произвольный файл, переданный в аргументе:

По умолчанию strace выводит много лишней информации. Флаг -P с аргументом заставляет strace выводить только обращения к указанному файлу:

Пример: многопоточные программы

Утилита strace может помочь и при работе с многопоточной программой. Следующая программа пишет в стандартный поток вывода из двух потоков:

Собирать её надо, естественно, со специальным приветом линковщику — флагом -pthread:

Флаг -f , как и в случае с обычными процессами, добавит в начало каждой строки pid процесса.

Естественно, речь идёт не об идентификаторе потока в смысле реализации стандарта POSIX Threads, а о номере, используемом планировщиком задач в Linux. С точки зрения последнего нет никаких процессов и потоков — есть задачи, которые надо распределить по доступным ядрам машины.

При работе в несколько потоков системных вызовов становится слишком много:

Имеет смысл ограничиться только управлением процессами и системным вызовом write :

Кстати, вопросы. Какой системный вызов используется для создания нового потока? Чем такой вызов для потоков отличается от вызова для процессов?

Мастер-класс: стек процесса в момент системного вызова

Одна из недавно появившихся в strace возможностей — отображение стека вызовов функций в момент системного вызова. Простой пример:

Естественно, вывод программы при этом становится очень объёмным, и, помимо флага -k (отображение стека вызовов), имеет смысл фильтровать системные вызовы по имени:

Мастер-класс: инъекция ошибок

И ещё одна новая и очень полезная возможность: инъекция ошибок. Вот программа, пишущая две строки в поток вывода:

Отслеживаем оба вызова write:

А теперь используем выражение inject , чтобы вставить ошибку EBADF во все вызовы write:

Интересно, что ошибки возвращают все вызовы write , включая вызов, скрытый за perror. Имеет смысл возвращать ошибку только для первого из вызовов:

Тип ошибки указывать не обязательно:

В сочетании с другими флагами можно «ломать» обращения к конкретному файлу. Пример:

Помимо инъекций ошибок, можно вводить задержки при выполнении вызовов или получении сигналов.

Послесловие

Утилита strace — простой и надёжный инструмент. Но помимо системных вызовов отлаживать случается и другие аспекты работы программ и операционной системы. Например, отслеживать вызовы динамически линкуемых библиотек умеет ltrace, заглянуть в работу операционной системы могут SystemTap и ftrace, а глубоко исследовать производительность программ позволяет perf. Тем не менее именно strace — первая линия обороны в случае проблем с собственными и чужими программами, и использую я её минимум пару раз в неделю.

Словом, любите Unix, читайте man 1 strace и не стесняйтесь подглядывать за вашими программами!

Источник

Оцените статью