LINUX_book
456 pág.

LINUX_book


DisciplinaLinux714 materiais1.843 seguidores
Pré-visualização50 páginas
in size
and is allocated as expected at 0x4012e000.
Line #19: Closes the file descriptor for libc.
Line #20: The only system call from the actual program code. This is the same
open call from the source code just listed.
Line #21: Exits the process with a return code of 5.
2.2.4 Same Program Built Statically
Statically built programs do not require any external libraries for program
initialization. This means there is no need to find or load any shared libraries,
making the program initialization much simpler.
ion 230% gcc main.c -o main -static
ion 231% strace main
execve(\u201c./main\u201d, [\u201cmain\u201d], [/* 64 vars */]) = 0
fcntl64(0, F_GETFD) = 0
fcntl64(1, F_GETFD) = 0
fcntl64(2, F_GETFD) = 0
uname({sys=\u201dLinux\u201d, node=\u201dion\u201d, ...}) = 0
geteuid32() = 7903
getuid32() = 7903
getegid32() = 200
getgid32() = 200
brk(0) = 0x80a3ce8
brk(0x80a3d08) = 0x80a3d08
brk(0x80a4000) = 0x80a4000
2.2 What Is strace?
54 strace and System Call Tracing Explained Chap. 2
brk(0x80a5000) = 0x80a5000
open(\u201c/tmp/foo\u201d, O_RDONLY) = -1 ENOENT (No such file or
\u27a5directory)
_exit(5) = ?
The strace output is quite different when the program is linked statically. There
are some other system calls (the purpose of which is not important for this
discussion), but note that the program does not load libc or any other library.
Also worth nothing is that ltrace will not show any output for this program
since it is built statically.
2.3 IMPORTANT STRACE OPTIONS
This section is not meant to be a replacement for the strace manual. The strace
manual does a good job of documenting issues and options for strace but does
not really describe when to use the various options. The focus of this section is
to briefly describe the important strace options and when to use them.
2.3.1 Following Child Processes
By default strace only traces the process itself and not any child processes that
may be spawned. There are several reasons why you may need or want to trace
all of the child processes as well, including:
\u261e Tracing the activity of a command line shell.
\u261e Tracing a process that will create a daemon process that will continue to
run after the command line tool exits.
\u261e Tracing inetd or xinetd to investigate problems relating to logging on to a
system or for tracing remote connections to a system (an example of this is
included later in this chapter).
\u261e Some processes spawn worker processes that perform the actual work while
the parent process manages the worker process pool.
To trace a process and all of its children, use the -f flag. Tracing with -f will
have no effect if the process does not fork off any children. However, the output
will change once a child is created:
rt_sigprocmask(SIG_SETMASK, [INT], [INT], 8) = 0
rt_sigprocmask(SIG_BLOCK, [INT], [INT], 8) = 0
rt_sigprocmask(SIG_SETMASK, [INT], [INT], 8) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [INT], 8) = 0
fork() = 24745
[pid 14485] setpgid(24745, 24745 <unfinished ...>
552.3 Important strace Options
[pid 24745] gettimeofday( <unfinished ...>
[pid 14485] <... setpgid resumed> ) = 0
In particular, the system calls are prefixed with a process ID to distinguish the
various processes being traced. The grep utility can then be used to separate
the strace output for each process ID.
Note: As a rule of thumb, always use the -f switch unless you
specifically want to exclude the output from the child processes.
2.3.2 Timing System Call Activity
The strace tool also can be used to investigate some types of performance
problems. In particular, the timed tracing features can provide information
about where a process is spending a lot of time.
Be very careful not to make incorrect assumptions about where the time
is spent. For example, the -t switch will add a timestamp (time of day) to the
strace output, but it is a timestamp between the system call entry times. In
other words, subtracting two timestamps gives time for the first system call
and the user code that is run between the two system calls.
There are two other ways to include a timestamp: -tt (time of day with
microseconds) and -ttt (number of seconds since the epoch with microseconds).
Note: The -tt option is usually the best option to capture a timestamp.
It includes the time of day with microseconds.
If you\u2019re interested in getting the time between system calls, you can use the
-r switch:
ion 235% strace -r main
0.000000 execve(\u201c./main\u201d, [\u201cmain\u201d], [/* 64 vars */]) = 0
0.000801 fcntl64(0, F_GETFD) = 0
0.000090 fcntl64(1, F_GETFD) = 0
0.000055 fcntl64(2, F_GETFD) = 0
0.000052 uname({sys=\u201dLinux\u201d, node=\u201dion\u201d, ...}) = 0
0.000305 geteuid32() = 7903
0.000038 getuid32() = 7903
0.000038 getegid32() = 200
0.000037 getgid32() = 200
0.000076 brk(0) = 0x80a3ce8
0.000048 brk(0x80a3d08) = 0x80a3d08
0.000040 brk(0x80a4000) = 0x80a4000
0.000054 brk(0x80a5000) = 0x80a5000
56 strace and System Call Tracing Explained Chap. 2
0.000058 open(\u201c/tmp/foo\u201d, O_RDONLY) = -1 ENOENT (No such file or
\u27a5directory)
0.000092 _exit(5) = ?
Again, keep in mind that this is the time between two system call entries and
includes the time for the system call and the user code. This usually has limited
usefulness.
A more useful method of timing actual system calls is the -T switch. This
provides the actual time spent in a system call instead of the time between
system calls. It is slightly more expensive because it requires two timestamps
(one for the system call entry and one for the system call exit) for each system
call, but the results are more useful.
ion 249% strace -T main
execve(\u201c./main\u201d, [\u201cmain\u201d], [/* 64 vars */]) = 0
fcntl64(0, F_GETFD) = 0 <0.000016>
fcntl64(1, F_GETFD) = 0 <0.000012>
fcntl64(2, F_GETFD) = 0 <0.000012>
uname({sys=\u201dLinux\u201d, node=\u201dion\u201d, ...}) = 0 <0.000013>
geteuid32() = 7903 <0.000012>
getuid32() = 7903 <0.000012>
getegid32() = 200 <0.000011>
getgid32() = 200 <0.000012>
brk(0) = 0x80a3ce8 <0.000012>
brk(0x80a3d08) = 0x80a3d08 <0.000011>
brk(0x80a4000) = 0x80a4000 <0.000011>
brk(0x80a5000) = 0x80a5000 <0.000012>
open(\u201c/tmp/foo\u201d, O_RDONLY) = -1 ENOENT (No such file or
\u27a5directory) <0.000019>
_exit(5) = ?
The time spent in the system call is shown in angle brackets after the system
call (seconds and microseconds).
Another useful way to time system calls is with the -c switch. This switch
summarizes the output in tabular form:
ion 217% strace -c main
execve(\u201c./main\u201d, [\u201cmain\u201d], [/* 64 vars */]) = 0
% time seconds usecs/call calls errors syscall
______ __________ _________ ________ ________ ______________
 40.00 0.000030 30 1 1 open
 25.33 0.000019 6 3 fcntl64
 16.00 0.000012 3 4 brk
 5.33 0.000004 4 1 uname
 4.00 0.000003 3 1 getuid32
 4.00 0.000003 3 1 getegid32
 2.67 0.000002 2 1 getgid32
57
 2.67 0.000002 2 1 geteuid32
\u2014\u2014\u2014 \u2014\u2014\u2014\u2014\u2014 \u2014\u2014\u2014\u2014\u2014 \u2014\u2014\u2014\u2014 \u2014\u2014\u2014\u2014 \u2014\u2014\u2014\u2014\u2014\u2014\u2014
100.00 0.000075 13