The strace command is useful for debugging any command or a script. Thachievedheived by using a concept called command on command. The strace command has some other sister commands like ps, pstree, lsof etc.
What is Linux strace command do?
The primary purpose of the strace command is to show system calls which are created by the kernel when working with some process. Say suppose you write a program and want to see how it interacts with the system when it is executed, strace is your friend. The strace command is just a light debugger for your programs and command. In below example, we tried to run the pwd command and showed you what steps will be taken place.
Syntax of strace command
strace <command>
Example:
root@linuxnix:~# strace pwd
execve("/bin/pwd", ["pwd"], [/* 73 vars */]) = 0
brk(NULL) = 0x148c000
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f5f89746000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=162567, ...}) = 0
mmap(NULL, 162567, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f5f8971e000
close(3) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0P\t\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1868984, ...}) = 0
mmap(NULL, 3971488, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f5f89159000
mprotect(0x7f5f89319000, 2097152, PROT_NONE) = 0
mmap(0x7f5f89519000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1c0000) = 0x7f5f89519000
mmap(0x7f5f8951f000, 14752, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f5f8951f000
close(3) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f5f8971d000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f5f8971c000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f5f8971b000
arch_prctl(ARCH_SET_FS, 0x7f5f8971c700) = 0
mprotect(0x7f5f89519000, 16384, PROT_READ) = 0
mprotect(0x606000, 4096, PROT_READ) = 0
mprotect(0x7f5f89748000, 4096, PROT_READ) = 0
munmap(0x7f5f8971e000, 162567) = 0
open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=2981280, ...}) = 0
mmap(NULL, 2981280, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f5f88e81000
close(3) = 0
brk(NULL) = 0x148c000
brk(0x14ad000) = 0x14ad000
getcwd("/root", 4096) = 6
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 5), ...}) = 0
write(1, "/root\n", 6/root
) = 6
close(1) = 0
close(2) = 0
exit_group(0) = ?
+++ exited with 0 +++Let me try to explain what just happened:
Step A: It shows kernel is searched for the pwd command in PATH variable and execute that.
execve("/bin/pwd", ["pwd"], [/* 73 vars */]) = 0Step B: Kernel checks if the user has access to read this file or not.
Step C: Access required library files for executing this command.
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)…………………………..
Step X: Gets current working directory.
getcwd("/home/surendra/code/sh", 4096) = 23
Step Y: Writes the current directory output to a file descriptor.
Output:
write(1, "/root\n", 6/root
Step Z: Closes and exit the command execution
close(1) = 0 close(2) = 0 exit_group(0) = ? +++ exited with 0 +++
I skipped many steps between Step C and Step X intentionally to show many steps are involved. And it is out of this post scope to explain each thing.
So the primary purpose of the strace command is to trace Kernel calls and see if there is an issue within your command or shell script execution.
Below are some frequently used command line options when using Strace command.
Simple strace for a command
Just execute the pwd command and see what happens.
Example:
surendra@linuxnix:~/code/sh$ strace pwd
execve("/bin/pwd", ["pwd"], [/* 68 vars */]) = 0
brk(NULL) = 0x735000
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
..........
brk(0x756000) = 0x756000
getcwd("/home/surendra/code/sh", 4096) = 23
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 5), ...}) = 0
write(1, "/home/surendra/code/sh\n", 23/home/surendra/code/sh
) = 23
close(1) = 0
close(2) = 0
exit_group(0) = ?
+++ exited with 0 +++Trace a particular system call with strace
The strace command can be used to filter out particular system call without the help of grep. Use -e to specify which system call you want to see.
strace -e <call-type> <command>
Example Output:
surendra@linuxnix:~/code/sh$ strace -e open pwd
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
/home/surendra/code/sh
+++ exited with 0 +++Some of the frequently used system call options are
execve, access, open, read, and write fstat, getrlimit, getdents, ioctl and statfs. close and brk mmap and mprotect
Trace multiple systems calls for a command
We can trace multiple system calls instead of one as shown below.
strace -e trace=open, write <command>
Example:
surendra@linuxnix:~/code/sh$ strace -e trace=open,write pwd
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
write(1, "/home/surendra/code/sh\n", 23/home/surendra/code/sh
) = 23
+++ exited with 0 +++Trace network calls.
One of the system call option available is a network; We can use this to see if any network calls are happening or not.
Example:
root@linuxnix:/home/surendra# strace -e trace=network ifconfig
socket(PF_LOCAL, SOCK_DGRAM, 0) = 3
socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 4
socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP) = 5
docker0 Link encap:Ethernet HWaddr 02:42:5a:71:90:c8
inet addr:172.17.0.1 Bcast:0.0.0.0 Mask:255.255.0.0
UP BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
Trace a PID of process.
strace -p <pid>
Example(clipped):
recvmsg(5, 0x7ffede033080, 0) = -1 EAGAIN (Resource temporarily unavailable)
recvmsg(12, 0x7ffede0333b0, 0) = -1 EAGAIN (Resource temporarily unavailable)
recvmsg(20, 0x7ffede0333b0, 0) = -1 EAGAIN (Resource temporarily unavailable)
poll([{fd=3, events=POLLIN}, {fd=5, events=POLLIN}, {fd=9, events=POLLIN|POLLPRI}, {fd=12, events=POLLIN}, {fd=14, events=POLLIN}, {fd=20, events=POLLIN}, {fd=21, events=POLLIN}], 7, 0) = 0 (Timeout)
recvmsg(5, {msg_name(0)=NULL, msg_iov(1)=[{"\34\0*\331\n\0\240\4\\\1\0\0\247\274F\2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 4096}], msg_controllen=0, msg_flags=0}, 0) = 32
recvmsg(5, 0x7ffede033270, 0) = -1 EAGAIN (Resource temporarily unavailable)
recvmsg(5, 0x7ffede033270, 0) = -1 EAGAIN (Resource temporarily unavailable)
recvmsg(5, 0x7ffede033270, 0) = -1 EAGAIN (Resource temporarily unavailable)
recvmsg(5, 0x7ffede033270, 0) = -1 EAGAIN (Resource temporarily unavailable)
recvmsg(5, 0x7ffede0333b0, 0) = -1 EAGAIN (Resource temporarily unavailable)
recvmsg(12, 0x7ffede0333b0, 0) = -1 EAGAIN (Resource temporarily unavailable)
recvmsg(20, 0x7ffede0333b0, 0) = -1 EAGAIN (Resource temporarily unavailable)
poll([{fd=3, events=POLLIN}, {fd=5, events=POLLIN}, {fd=9, events=POLLIN|POLLPRI}, {fd=12, events=POLLIN}, {fd=14, events=POLLIN}, {fd=20, events=POLLIN}, {fd=21, events=POLLIN}], 7, 14List all calls and time for a command
strace -c <command>
Example:
root@linuxnix:/home/surendra# strace -c pwd /home/surendra % time seconds usecs/call calls errors syscall ------ ----------- ----------- --------- --------- ---------------- 0.00 0.000000 0 1 read 0.00 0.000000 0 1 write 0.00 0.000000 0 3 open 0.00 0.000000 0 5 close 0.00 0.000000 0 4 fstat 0.00 0.000000 0 9 mmap 0.00 0.000000 0 4 mprotect 0.00 0.000000 0 1 munmap 0.00 0.000000 0 3 brk 0.00 0.000000 0 3 3 access 0.00 0.000000 0 1 execve 0.00 0.000000 0 1 getcwd 0.00 0.000000 0 1 arch_prctl ------ ----------- ----------- --------- --------- ---------------- 100.00 0.000000 37 3 total
Trace a process with time stamp
For relative time stamp
strace -r <command>
Example(Clipped):
root@linuxnix:/home/surendra# strace -r pwd
0.000000 execve("/bin/pwd", ["pwd"], [/* 72 vars */]) = 0
0.000207 brk(NULL) = 0x164a000
0.000034 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
0.000028 mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f1775103000
0.000028 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
0.000022 open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
0.000022 fstat(3, {st_mode=S_IFREG|0644, st_size=162567, ...}) = 0
0.000022 mmap(NULL, 162567, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f17750db000
0.000019 close(3) = 0
0.000019 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
0.000023 open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
0.000020 read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0P\t\2\0\0\0\0\0"..., 832) = 832
0.000040 fstat(3, {st_mode=S_IFREG|0755, st_size=1868984, ...}) = 0For prefixing time of the day
strace -t <command>
Example(Clipped output):
root@linuxnix:/home/surendra# strace -t pwd
06:55:40 execve("/bin/pwd", ["pwd"], [/* 72 vars */]) = 0
06:55:40 brk(NULL) = 0x2213000
06:55:40 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
06:55:40 mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f2fa248c000
06:55:40 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
06:55:40 open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
06:55:40 fstat(3, {st_mode=S_IFREG|0644, st_size=162567, ...}) = 0
06:55:40 mmap(NULL, 162567, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f2fa2464000
06:55:40 close(3) = 0
06:55:40 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
06:55:40 open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3For prefixing time with microseconds
strace -tt <command>
Example:
root@linuxnix:/home/surendra# strace -tt pwd
06:56:40.430679 execve("/bin/pwd", ["pwd"], [/* 72 vars */]) = 0
06:56:40.430916 brk(NULL) = 0x1890000
06:56:40.430984 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
06:56:40.431046 mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f4335261000
06:56:40.431080 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
06:56:40.431106 open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
06:56:40.431129 fstat(3, {st_mode=S_IFREG|0644, st_size=162567, ...}) = 0
06:56:40.431155 mmap(NULL, 162567, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f4335239000For Epoch time as well as microseconds
strace -ttt <command>
Example:
root@linuxnix:/home/surendra# strace -ttt pwd
1505768216.612804 execve("/bin/pwd", ["pwd"], [/* 72 vars */]) = 0
1505768216.613087 brk(NULL) = 0x21a7000
1505768216.613135 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
1505768216.613172 mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd88413d000
1505768216.613202 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
1505768216.613223 open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
1505768216.613246 fstat(3, {st_mode=S_IFREG|0644, st_size=162567, ...}) = 0
1505768216.613268 mmap(NULL, 162567, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fd884115000
1505768216.613287 close(3) = 0Save traced command output to a file
strace -o <file_to_save> <command>
Example:
root@linuxnix:/home/surendra# strace -o pwd.txt pwd /home/surendra
In our next post, we will see ltrace and mtrace commands.
Latest posts by Surendra Anne (see all)
- Docker: How to copy files to/from docker container - June 30, 2020
- Anisble: ERROR! unexpected parameter type in action:
Fix - June 29, 2020 - FREE: JOIN OUR DEVOPS TELEGRAM GROUPS - August 2, 2019
- Review: Whizlabs Practice Tests for AWS Certified Solutions Architect Professional (CSAP) - August 27, 2018
- How to use ohai/chef-shell to get node attributes - July 19, 2018
