How do I use strace to trace system calls made by a command?
Table of Contents
- Introduction
- Usage
- Performance Analysis
- Compressing Output
- Looping Collection
- SELinux Context Printing
Introduction
The command strace
is used to trace system calls and signals. It is a great tool to use when debugging an application and is often requested by Red Hat support engineers to examine certain issues which may arise within the operating system and its programs.
Usage
-
To record the system calls issued by running
command
and output trace information to a file called/tmp/strace.txt
, run the following:-
RHEL 6.7+ and RHEL 7 with strace 4.7 or above:
# strace -fvttTyy -s 256 -o /tmp/strace.txt command
-
Older RHEL releases with strace below version 4.7. This includes all releases of RHEL 4, RHEL 5, and RHEL 6.6 or below:
# strace -fvttT -s 256 -o /tmp/strace.txt command
-
-
You may also attach to an already-running process with the
-p
option and the PID of the process as follows:-
RHEL 6.7+ and RHEL 7 with strace 4.7 or above:
# strace -fvttTyy -s 256 -o /tmp/strace.txt -p PID
-
Older RHEL releases with strace below version 4.7. This includes all releases of RHEL 4, RHEL 5, and RHEL 6.6 or below:
# strace -fvttT -s 256 -o /tmp/strace.txt -p PID
(where
PID
is replaced with the PID number of the process)
-
Options
The options used above are added to provide more accuracy and completeness to traces.
The options explained as follows:
-f
causes child processes to be captured into the same file, separate processes are prepended with their PID number in the trace output-v
prints unabbreviated versions of environment, stat, and similar calls-tt
prints the start time of each line, including microseconds-T
shows the time between the beginning and end of the system call-yy
prints paths associated with file descriptors and sockets (available in strace 4.7 and above)-s 256
prints the first 256 characters of any strings, the default value of32
often causes useful information to be missed. Using a large value such as-s 4096
is not recommended because it slows down the process too much; this should be restricted to specific use cases where the user is interested in seeing file content and/or complete messages.-o /tmp/strace.txt
outputs the trace to a text file for retrospective analysis, as the output is often large with long lines which makes live analysis difficult to impossible-e trace=set
allows for the tracing of specific system calls, i.e.-e trace=open,close,read,write
, instead of the default of-e trace=all
Performance Analysis
-
strace
can also be used to provide a count and call-time summary of all system calls over the data collection period. -
This mode is enabled with the
-c
flag. -
Output follows the format of this example:
# strace -c -p PID Process PID attached - interrupt to quit ^CProcess PID detached % time seconds usecs/call calls errors syscall ------ ----------- ----------- --------- --------- ---------------- 100.00 0.010116 66 153 select 0.00 0.000000 0 165 gettimeofday ------ ----------- ----------- --------- --------- ---------------- 100.00 0.010116 318 total
Compressing Output
-
In the case of very verbose output, it may be desirable to compress the trace output on the fly.
-
This can be done with the following command in the
bash
shell# strace -fvttTyy -s 256 command 3>&1 1>&2 2>&3 3>&- | gzip -9c > strace.txt.gz
-
If this redirection does not work in other shells like
ksh
,zsh
,fish
, orcsh
, this alternate command using named pipes also works:# mkfifo /tmp/catcher; cat /tmp/catcher | gzip -9c > /tmp/strace.txt.gz & strace -fvttTyy -s 4096 -o /tmp/catcher command
-
Remove named pipe when finished
# rm -f /tmp/catcher
-
In both of these examples, an already-running process can be traced by replacing
command
with-p PID
.
Looping Collection
strace itself does not have the capability to "roll over" into multiple log files, however a script can do this, as described at:
Note that depending on the issue being investigated, rolling over the strace file may remove a file descriptor creation and make the issue more difficult or impossible to troubleshoot. The linked script should only be used in situations where an FD is open for a shorter amount of time than the loop run.
SELinux Context Printing
On SELinux enabled systems, with recent strace (RHEL8.4+), it's possible to additionally print the context of the process being traced along with the context of the various components (e.g. files, file descriptors, etc.).
This is done through adding the following option:
--secontext
to display only the SELinux type (e.g.unconfined_t
for a process)--secontext=full
to display the full SELinux tuple (e.g.unconfined_u:unconfined_r:unconfined_t:s0
for a process)--secontext=mismatch
to display only the SELinux type but show unexpected context compared to the SELinux context database
For ancient releases not having --secontext
option, you may use the non-official binary available in Renaud Métrich's Red Hat Personal Space.
Comments