Friday, February 01, 2008

Random notes on proc & process status

proc file system gives a view of the processes, including kernel, running in the Linux system. Writing into some of the files under /proc changes the state of the processes in memory. For e.g. you can change how much maximum shared memory you want the kernel to allow by changing the file /proc/sys/kernel/shmmax. This will take effect without rebooting the system, since it directly modifies the value of that particular kernel variable. But most of these changes are transient. Hence you will lose them when you reboot your system.

You can examine the state of the process using proc file system. Each process running in the system will have an entry under /proc/pid, where pid is the process ID. There are good tutorials that explain about each entry under this directory. You can google for them. But I could not find explanation for some entries, particularly status file. Thats the objective of this blog.

For a single-threaded process, you will find all the information about the state of the process under /proc/pid itself. For a multi-threaded process, the /proc/pid will have a subdirectory called task. This directory contains contains one subdirectory per thread, including the main thread: /proc/pid/task/tid1, /proc/pid/task/tid2, etc. The main thread has the thread ID same as the process ID.

The easiest way to find out if a given process is multi threaded or not is to examine the /proc/pid/task directory. If it contains many subdirectories, its a multi-threaded process. Otherwise, it could be a single threaded one.

One particular file that you will find very useful to understand the status of the threads (the only thread, in case of a single threaded application) is /proc/pid/task/tid/status. A sample status file is given below:
Name: a.out
State: S (sleeping)
SleepAVG: 88%
Tgid: 15155
Pid: 15155
PPid: 1
TracerPid: 0
Uid: 9929 9929 9929 9929
Gid: 9929 9929 9929 9929
FDSize: 256
Groups: 10 9929
VmSize: 2792 kB
VmLck: 0 kB
VmRSS: 696 kB
VmData: 40 kB
VmStk: 504 kB
VmExe: 2 kB
VmLib: 2186 kB
StaBrk: 0804a000 kB
Brk: 096fe000 kB
StaStk: bff854b0 kB
ExecLim: ffffffff
Threads: 1
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000000000000
SigCgt: 000000027f00000e
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000

Let me explain each of the fields in this file.

Name: The name of the binary of this process.
State: The current state of the process. There are totally seven states of a process: running, sleeping, disk sleep, stopped, tracing stopped, zombie and dead. I will explain these states in a separate blog :-)
SleepAVG: I think this is average sleep time. I am not sure.
Tgid: Thread group ID. This is a single value, which implies that a thread cannot be a part of more than one thread group.
Pid: Process ID.
PPid: Parent process ID.
TracerPid: If the process is currently being traced, for e.g. using strace, this will contain the tracer's PID.
Uid: real user ID, effective user ID, saved user ID and the file system user ID.
Gid: real group ID, effective group ID, saved group ID and the file system group ID.
FDSize: What is the size of the file descriptor table for this process.
Groups: List of groups that the owner of the process belongs to. (I am not sure about this info).
VmSize: Total virtual memory size.
VmLck: Locked virtual memory size. (Refer to the man page for mmap and mlockall).
VmRSS: Resident set size. i.e. how much of the total virtual memory is resident in RAM.
VmData: How much of the virtual memory is data.
VmStk: How much of the virtual memory is stack.
VmExe: How much of the virtual memory is executable (a.k.a text).
VmLib: How much of the virtual memory shared object libraries occupy.
StaBrk: The starting address of the data that could be grown using sbrk() call.
Brk: The top of the data that has been reached using sbrk() call.
StaStk: I am not sure about this value.
ExecLim: I am not sure about this value either :-(
Threads: The number of threads this process has.
SigPnd: Signals pending to be delivered to this thread.
ShdPnd: Shared pending signals. I am not sure how this value is used.
SigBlk: Signals that the thread explicitly blocked. These signals will be delivered when the thread unblocks the signal.
SigIgn: Signals that the thread decided to ignore. There is a difference between blocking a signal and ignoring a signal. Pickup APUE and read the chapter on signals.
SigCgt: Signals that the thread decided to catch, by installing a signal handler. This is done through sigaction() function.
CapInh, CapPrm, CapEff: All I know is these are related to capabilities and they stand for capability inheritable, capability permitted and capability effective. I don't have an understanding of what they are.

Okay. Hopefully that helps in understanding the status of a thread when you look at status file next time.

Happy hacking and have a good weekend.