A detailed description of the use of the strace command under Linux

  

The strace command is a powerful tool that displays all system calls issued by user space programs.

strace displays the parameters of these calls and returns the value in symbolic form. Strace receives information from the kernel and does not need to build the kernel in any special way.

The following record several common options.

1 -f -F option tells strace to track the progress of fork and vfork

2 -o xxx.txt Documents.

3 -e execve only records system calls such as execve

—————————————&mdash ;———

The process fails to start, the software runs slowly, and the program's "SegmentFault" is a headache for every Unix system user,

This article demonstrates how to use the three commonly used debugging tools truss, strace, and ltrace to quickly diagnose software "difficulty" through three practical cases.



truss and strace are used to track the system call or signal generation of a process, while ltrace is used to track the process call library functions. Truss is a debugging program developed for System V R4 in the early days. Most Unix systems including Aix and FreeBSD come with this tool.

While strace was originally written for SunOS system, ltrace first appeared in GNU/DebianLinux.

These two tools have now been ported to most Unix systems. Most Linux distributions come with strace and ltrace, and FreeBSD can also install them via Ports.


Not only can you debug a new program from the command line, but you can also bind truss, strace, or ltrace to an existing PID to debug a running program. The basic usage of the three debugging tools is basically the same. The following only introduces the three common, and is the most commonly used three command line parameters:


-f : In addition to tracking the current process, Also track its child processes.

-o file : Writes the output to the file file instead of displaying it to the standard error output (stderr).

-p pid : Bind to a running process corresponding to pid. This parameter is often used to debug background processes.


Using the three parameters above, you can basically do most of the debugging tasks. Here are a few command line examples:

truss -o ls.truss ls - Al: Traces the run of ls -al and writes the output to the file /tmp/ls.truss.

strace -f -o vim.strace vim: Traces the operation of vim and its child processes, and writes the output to the file vim.strace.

ltrace -p 234: Track a process that is already running with a pid of 234.


The output format of the three debugging tools is also very similar, taking strace as an example:


brk(0) = 0×8062aa8< Br>

brk(0×8063000) = 0×8063000

mmap2(NULL, 4096, PROT_READ, MAP_PRIVATE, 3, 0×92f) = 0×40016000


Each line is a system call, the left side of the equal sign is the name of the function called by the system and its parameters, and the right side is the return value of the call. Truss, strace, and ltrace work in much the same way. They use ptrace system calls to track the progress of debugging operations. The detailed principles are beyond the scope of this article. Interested parties can refer to their source code.

To give two examples to demonstrate how to use these three debugging tools to diagnose software intractable diseases":


Case 1: Running a clint with a Segment Fault error


Operating System
:FreeBSD-5.2.1-release

clint is a C++ static source code analysis tool that is installed through Ports. Run:


# clint foo.cpp

Segmentation fault (core dumped)

Meet on Unix system >Segmentation Fault> The pop-up "Illegal Operation" dialog box in MS Windows
is just as annoying. OK, we use truss to clint







# tail clint.truss

739: read(0×6,0×806f000,0×1000) = 4096 (0×1000)

739: fstat(6,0xbfbfe4d0 = 0 (0× 0)

739: fcntl(0×6,0×3,0×0) = 4 (0×4)

739: fcntl(0×6 ,0×4,0×0) = 0 (0×0)

739: close(6) = 0 (0×0)

739: stat(”/root/.clint/plugins”,0xbfbfe680) ERR#2 ‘No such file or directory’

SIGNAL 11

SIGNAL 11

Process stopped because of: 16

process exit, rval = 139

We use truss to track the clint's system call execution and output the result to the file clint.truss, then use tail to view the last few lines.

Note the last system call executed by clint (the fifth last line): stat(”/root/.clint/plugins”,0xbfbfe680) ERR#2 ‘No such file or directory’, the problem is Out of here: clint can't find the directory ”/root/.clint/plugins”, which caused a segmentation error. How to solve it? Very simple: mkdir -p /root/.clint/plugins, but this time running clint will still "Segmentation Fault". Continue to use truss tracking, found that clint also needs this directory ” /root /.clint /plugins /python & rdquo;, after the establishment of this directory clint finally can run normally.


Case 2: vim startup speed is significantly slower


Operating System: FreeBSD-5.2.1-release

vim The version is 6.2.154. After running vim from the command line, it takes about half a minute to enter the editing interface, and there is no error output. Carefully checked that .vimrc and all vim scripts are not misconfigured, and there is no solution to similar problems on the Internet. Is it hacking source code? No need to use truss to find the problem:


# truss -f -D -o vim.truss vim


here-D The purpose of the parameter is to add a relative timestamp before each line of output, which is the time it takes to execute a system call. We only need to pay attention to which system calls take a long time, useless to carefully view the output file vim.truss, and quickly found the suspect:


735: 0.000021511 socket(0× ;2,0×1,0×0) = 4 (0×4)

735: 0.000014248 setsockopt(0×4,0×6,0×1,0xbfbfe3c8,0×4) = 0 ( 0× 0)

Copyright © Windows knowledge All Rights Reserved