- 10 Strace Commands for Troubleshooting and Debugging Linux Processes
- How to Install Strace Process Monitoring Tool in Linux
- 1. Trace Linux Command System Calls
- 2. Trace Linux Process PID
- 3. Get Summary of Linux Process
- 4. Print Instruction Pointer During System Call
- 5. Show Time of Day For Each Trace Output Line
- 6. Print Command Time Spent in System Calls
- 7. Trace Only Specific System Calls
- 8. Trace System Calls Based on a Certain Condition
- 9. Redirect Trace Output to File
- 10. Show Some Debugging Output of Strace
- If You Appreciate What We Do Here On TecMint, You Should Consider:
- Debugging Tip: Trace the Process and See What It is Doing with strace
- How to track and trace a Linux process
- Trace a Linux process using ps command
- Strace: another easy way to trace a system process
- strace example
- Strace в Linux: история, устройство и использование
- Содержание
- Происхождение видов
- Устройство strace в двух словах: Piglet Trace
- Азы: запуск программы под управлением strace
- Азы: присоединение к процессу на лету
- Пример: отслеживание дочерних процессов
- Пример: пути к файлам вместо дескрипторов
- Пример: отслеживание обращений к файлам
- Пример: многопоточные программы
- Мастер-класс: стек процесса в момент системного вызова
- Мастер-класс: инъекция ошибок
- Послесловие
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,
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([
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,
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,
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.
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.
Источник
Debugging Tip: Trace the Process and See What It is Doing with strace
strace is a useful diagnostic, instructional, and debugging tool. It can save lots of headache. System administrators, diagnosticians and trouble-shooters will find it invaluable for solving problems with programs for which the source is not readily available since they do not need to be recompiled in order to trace them. This is also useful to submit bug reports to open source developers.
Each line in the trace contains the system call name, followed by its arguments in parentheses and its return value.
Run strace against /bin/foo and capture its output to a text file in output.txt:
$ strace -o output.txt /bin/foo
You can strace the webserver process and see what it’s doing. For example, strace php5 fastcgi process, enter:
$ strace -p 22254 -s 80 -o /tmp/debug.lighttpd.txt
To see only a trace of the open, read system calls, enter :
$ strace -e trace=open,read -p 22254 -s 80 -o debug.webserver.txt
Where,
- No ads and tracking
- In-depth guides for developers and sysadmins at Opensourceflare✨
- Join my Patreon to support independent content creators and start reading latest guides:
- How to set up Redis sentinel cluster on Ubuntu or Debian Linux
- How To Set Up SSH Keys With YubiKey as two-factor authentication (U2F/FIDO2)
- How to set up Mariadb Galera cluster on Ubuntu or Debian Linux
- A podman tutorial for beginners – part I (run Linux containers without Docker and in daemonless mode)
- How to protect Linux against rogue USB devices using USBGuard
Join Patreon ➔
- -o filename : Write the trace output to the file filename rather than to screen (stderr).
- -p PID : Attach to the process with the process ID pid and begin tracing. The trace may be terminated at any time by a keyboard interrupt signal (hit CTRL-C). strace will respond by detaching itself from the traced process(es) leaving it (them) to continue running. Multiple -p options can be used to attach to up to 32 processes in addition to command (which is optional if at least one -p option is given).
- -s SIZE : Specify the maximum string size to print (the default is 32).
Refer to strace man page for more information:
$ man strace
Источник
How to track and trace a Linux process
On this post we will show you how to track and trace a Linux process on the system with two tools, ps and strace command line tools. This system tools can help you to identify real system process and their origin.
On shared web hosting servers it is very common to face spam and malware issues. This issues can happen due to lot of reasons, and sometimes this outgoing spams or attacks are launched from system processes like perl scripts using lot of CPU resources.
On most of this cases, apparently it is “only” a perl process, but here come a few interesting questions: how do you know where is it coming from? How a Linux system process could mask its real name? What is the most easy and reliable way to find out where this Linux process was started?
Today we will try to answer all this questions with some quick and easy practical examples.
Trace a Linux process using ps command
Let’s see a real life example that happened days ago in a dedicated server I manage.
On one particular website there was an outgoing spam issue that was sending lot of emails, but no malware was found inside the public_html folder, also all email boxes passwords were changed, the same as the FTP/cPanel account password. Still, there was a way the attacker was using the Linux system to send outgoing emails.
The source of the emails was a process running under the “johndoe” user which was appearing to be malicious, and was not what it claimed to be:
As you see, the first thing to find out the process was to use the ps command, as you see below:
Replace “user” with your real system user.
After that, once you have the suspicious processes listed, use ll command to find out more information using its PID, as seen before:
As you see, the process claims to be “httpd” to hide itself (any process can change its own process-title), it is actually a perl process:
There was no script file associated with it, however. The script was most likely piped into the perl process to avoid putting anything on the filesystem where it would leave a trace.
I do not know how the script came to be running under this user, but this was a vulnerable WordPress installation with many outdated plugins and injected malware that could easily lead to this kind of issues.
Killing the rouge process was the best thing to do in this case:
Replace “59289” with the real process ID.
Strace: another easy way to trace a system process
strace is a very handy and useful tool used by system administrators for debugging and diagnostic system and process related problems where the source is not really clear and available when taking a quick and first look.
This debug tool allows programmers and system users to quickly find out how a program is interacting with the OS. It does this by monitoring system calls and signals.
As we will see in the next examples, strace outputs each line in the trace that includes the system call name, its arguments and the return value (inside the parentheses).
strace example
Let’s run strace against /bin/ls, and save the output into a file called ls.txt
To read the output, just run:
But that is just a basic strace example. The interesting part comes when you can strace the webserver process and find out what it is doing exactly. Let’s take a php-fpm process as example:
By pressing CTRL + C you will terminate the trace and it will be detached.
Fig 01. Screenshot from strace command example
You can also specify what you need to trace, for example, if you only need to trace the open and read system calls, you should specify that in the strace syntax, as you see below:
This quick strace example used a few command options, exaplained here:
Again, to read the output, just run:
Now you know how to trace a Linux process easily with two simple commands, with this information you can easily track a Linux process to find out what is doing exactly inside your server. strace takes a little bit more of time to understand from the manual, but it’s the definitive tool to trace a Linux process.
Источник
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 и изобилие системных вызовов, которые нас не интересуют.
Разделить стандартный поток вывода программы и вывод ошибок 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 и не стесняйтесь подглядывать за вашими программами!
Источник