456 pág.


DisciplinaLinux716 materiais1.852 seguidores
Pré-visualização50 páginas
Code Explained
The spawnChildProcess() function forks off a child process and runs ptrace with
PTRACE_TRACEME to ensure that the child process will stop when entering
or exiting a system call. The function then executes the process to be traced.
The traceChildProcess() function waits for the process to stop (presumably
due to a system call entry or exit) and then gets information about the stopped
process. It uses the ptrace call with PTRACE_GETREGS to get the registers
for the process. In particular, it tests the EAX register to see whether the process
is stopped on an entry or exit from a system call. When the traced process
stops on a system call entry, the EAX register will contain -ENOSYS. The EAX
normally contains the return code from the system call, and because the process
stopped on a system call entry, ENOSYS is an impossible return for a system
call to return (hence making it a good differentiator). For a system call exit,
the EAX register will be some value that is not -ENOSYS.
When a system call is entered, the original EAX will contain the system
call number. When a system call is identified, the system call calling convention
2.6 System Call Tracing Example
88 strace and System Call Tracing Explained Chap. 2
provides information about the arguments to the system call as shown in the
following code snippet:
char fileName[1024] = \u201c\u201d;
readString( stoppedPid, (void *)registers.ebx, fileName, 1024 ) ;
fprintf( stderr, \u201c\\u201d%s\\u201d, %#08x, %#08x\u201d,
 fileName, registers.ecx, registers.edx ) ;
The readString function reads in a single string at a particular address space
in the stopped process. For the open system call, the code reads the first
argument at the address stored in EBX. This is the file name for the open
system call.
This is how strace prints symbolic information for a system call. For every
system call, there is an opportunity to print the symbolic information that is
more descriptive than the numeric values in the registers.
If the EAX contains a value that is not minus ENOSYS, then the process
is presumed to be stopped at the exit of a system call. A positive value in EAX
means a successful completion of the system call, and the return code would
contain the successful return code of the system call. If the return code is
negative, it is assumed to be an error, and an error is printed in the strace
The main loop in traceChildProcess() continues until the traced process
exits for some reason:
while ( ( stoppedPid = waitpid( tracedPid, &status, 0 ) ) != -1 )
It continuously waits for the traced process to stop and then prints the
information for the system call entry and exit. Most of the source code is used
for formatting of the information.
As shown throughout this chapter, strace is one of the most useful problem
determination tools for Linux. It can quickly diagnose many types of problems,
and in many cases, it can help narrow down the scope of a problem with little
effort. The next chapter covers the /proc file system, which is also very useful
for problem determination.
1 When Linux operation names are appended with a number in parentheses, the number
directly refers to a man page section number. Section 1 is for executable programs or shell
commands, and section 2 is for system calls (functions provided by the kernel). Typing man 2
read will view the read system call man page from section 2.
The /proc Filesystem
One of the big reasons why Linux is so popular today is the fact that it combines
many of the best features from its UNIX ancestors. One of these features is the
/proc filesystem, which it inherited from System V and is a standard part of all
kernels included with all of the major distributions. Some distributions provide
certain things in /proc that others don\u2019t, so there is no one standard /proc
specification; therefore, it should be used with a degree of caution.
The /proc filesystem is one of the most important mechanisms that Linux
provides for examining and configuring the inner workings of the operating
system. It can be thought of as a window directly into the kernel\u2019s data
structures and the kernel\u2019s view of the user processes running on the system.
It appears to the user as a filesystem just like / or /home, so all the common file
manipulation programs and system calls can be used with it such as cat(1),
more(1), grep(1), open(2), read(2), and write(2)1. If permissions are sufficient,
writing values to certain files is also easily performed by redirecting output to
a file with the > shell character from a shell prompt or by calling the system
call write(2) within an application.
The goal of this chapter is not to be an exhaustive reference of the /proc
filesystem, as that would be an entire publication in itself. Instead the goal is
to point out and examine some of the more advanced features and tricks
primarily related to problem determination and system diagnosis. For more
general reference, I recommend reading the proc(5) man page.
C H A P T E R 3
Note: If you have the kernel sources installed on your system, I also
recommend reading /usr/src/linux/Documentation/filesystems/procfs.txt.
90 The /proc Filesystem Chap. 3
Along with viewing and manipulating system information, obtaining user
process information is another way in which the /proc filesystem shines. When
you look at the listing of files in /proc, you will immediately notice a large
number of directories identified by a number. These numbers represent process
IDs and contain more detailed information on that process ID within it. All
Linux systems will have the /proc/1 directory. The process with ID 1 is always
the \u201cinit\u201d process and is the first user process to be started on the system during
bootup. Even though this is a special program, it is a process just like any
other, and the /proc/1 directory will contain the same information as any other
process including the ls command you use to see the contents of this and any
other directory! The following sections will go into more detail on the most
useful information that can be found in the /proc/<pid>2 directory such as
viewing and understanding a process\u2019 address space, viewing CPU and memory
configuration information, and understanding settings that can greatly enhance
application and system troubleshooting.
3.2.1 /proc/self
As a quick introduction into how processes are represented in the /proc
filesystem, let\u2019s first look at the special link &quot;/proc/self.&quot; The kernel provides
this as a link to the currently executing process. Typing &quot;cd /proc/self&quot; will
take you directly into the directory containing the process information for your
shell process. This is because cd is a function provided by the shell (the currently
running process at the time of using the &quot;self&quot; link) and not an external program.
If you perform an ls -l /proc/self, you will see a link to the process directory
for the ls process, which goes away as soon as the directory listing completes
and the shell prompt returns. The following sequence of commands and their
associated output illustrate this.
Note: $$ is a special shell environment variable that stores the
shell\u2019s process ID, and &quot;/proc/<pid>/cwd&quot; is a special link provided by the
kernel that is an absolute link to the current working directory.
2 A common way of generalizing a process\u2019 directory name under the /proc filesystem is to use /
proc/<pid> considering a process\u2019 number is random with the exception of the init process.
penguin> echo $$
penguin> ls -l /proc/self
lrwxrwxrwx 1 root root 64 2003-10-13 08:04 /proc/self -> 2945
penguin> cd /proc/self
penguin> ls -l cwd
lrwxrwxrwx 1 dbehman build 0 2003-10-13 13:00 cwd -> /proc/2602
The main thing to understand in this example is that