8.1 Using strace

Before we start discussing system calls, it will be useful to present a command with which you can learn about and debug system calls. The strace command traces the execution of another program, listing any system calls the program makes and any signals it receives.

To watch the system calls and signals in a program, simply invoke strace, followed by the program and its command-line arguments. For example, to watch the system calls that are invoked by the hostname [1] command, use this command:

[1] hostname invoked without any flags simply prints out the computer's hostname to standard output.

% strace hostname 

This produces a couple screens of output. Each line corresponds to a single system call. For each call, the system call's name is listed, followed by its arguments (or abbreviated arguments, if they are very long) and its return value. Where possible, strace conveniently displays symbolic names instead of numerical values for arguments and return values, and it displays the fields of structures passed by a pointer into the system call. Note that strace does not show ordinary function calls.

In the output from strace hostname, the first line shows the execve system call that invokes the hostname program: [2]

[2] In Linux, the exec family of functions is implemented via the execve system call.

execve("/bin/hostname", ["hostname"], [/* 49 vars */]) = 0 

The first argument is the name of the program to run; the second is its argument list, consisting of only a single element; and the third is its environment list, which strace omits for brevity. The next 30 or so lines are part of the mechanism that loads the standard C library from a shared library file.

Toward the end are system calls that actually help do the program's work. The uname system call is used to obtain the system's hostname from the kernel,

uname({sys="Linux", node="myhostname", ...}) = 0 

Observe that strace helpfully labels the fields (sys and node) of the structure argument. This structure is filled in by the system call—Linux sets the sys field to the operating system name and the node field to the system's hostname. The uname call is discussed further in Section 8.15, "uname."

Finally, the write system call produces output. Recall that file descriptor 1 corresponds to standard output. The third argument is the number of characters to write, and the return value is the number of characters that were actually written.

write(1, "myhostname\n", 11)            = 11 

This may appear garbled when you run strace because the output from the hostname program itself is mixed in with the output from strace.

If the program you're tracing produces lots of output, it is sometimes more convenient to redirect the output from strace into a file. Use the option -o filename to do this.

Understanding all the output from strace requires detailed familiarity with the design of the Linux kernel and execution environment. Much of this is of limited interest to application programmers. However, some understanding is useful for debugging tricky problems or understanding how other programs work.