Learning Question
How can operating-system tools reveal what a running program is doing?
Runtime diagnosis works when observable clues are connected back to OS-managed state.
Tools such as ps, top, lsof, strace, and /proc do not show the source code’s intention directly.
They show process state, resource usage, open descriptors, system calls, memory mappings, and scheduling clues.
The first mental model is:
OS diagnostic tools are useful because they expose parts of the process state that the operating system already manages.
Process Lists
Tools such as ps show processes.
They may reveal:
- process ID
- parent process ID
- command
- user
- state
- CPU time
- memory-related fields
- terminal association
This information helps answer basic questions:
- Is the process still alive?
- Who started it?
- Which user is it running as?
- Is it sleeping, running, stopped, or defunct?
A process list is not a full explanation.
It is a starting point for connecting symptoms to OS-managed process state.
CPU and Memory Views
Tools such as top or similar monitors show changing resource usage.
High CPU usage may suggest CPU-bound execution or a busy loop.
Low CPU usage with no progress may suggest blocking, waiting, deadlock, external dependency delay, or no incoming work.
Memory numbers require care because virtual size, resident memory, shared mappings, and allocator behavior are not the same.
The useful habit is:
Treat resource numbers as clues about process state, not as direct explanations by themselves.
Open Files and Descriptors
Tools such as lsof can show open files, sockets, pipes, and devices associated with a process.
This can answer questions such as:
- Which log file is the process writing?
- Does it still hold a deleted file open?
- Which network sockets are open?
- Which pipes or terminals are connected?
This works because the OS tracks open resources per process.
The tool exposes part of the descriptor/resource relationship.
System Call Tracing
Tools such as strace on Linux can show system calls made by a process.
This is powerful because system calls are the boundary between user code and kernel-managed operations.
Tracing can reveal:
- which file a process tries to open
- whether permission is denied
- whether a read blocks or returns zero bytes
- which network calls are attempted
- whether a process is repeatedly polling or sleeping
- which signal is delivered
System call traces can be noisy.
The goal is not to memorize every call.
The goal is to identify which OS boundary the program is interacting with.
/proc as Process State
On Linux, /proc exposes kernel-managed process information through a file-like interface.
For example, /proc/<pid>/ can reveal details about:
- command-line arguments
- environment
- open file descriptors
- memory maps
- current working directory
- status fields
/proc is Linux-specific, but it illustrates a general idea:
The operating system can expose runtime state because it is already managing that state.
Exit Codes and Signals
When a command fails, its exit code or terminating signal is often the first durable clue.
An exit code may indicate program-defined failure.
A signal may indicate interruption, forced termination, broken pipe, invalid memory access, or another OS-level event.
Shells and supervisors use these results to decide what happened and what to do next.
The source code may contain the cause, but the OS-level result tells how the process ended.
Core Mental Model
Diagnosis improves when each observation is mapped to the OS concept behind it.
When using a tool, ask:
Is this showing process identity, scheduling state, memory mappings, open resources, system calls, process signals, or exit state?
Final Summary
Operating-system diagnostic tools expose the runtime structures that support programs: processes, descriptors, memory maps, system calls, resource usage, signals, and exit status.
They are most useful when their output is interpreted through the execution model rather than treated as isolated command output.