Linux Processes & Signals
Processes and fork/exec, process states, zombies and orphans and PID 1, signals, syscalls, file descriptors, and the PATH search.
9 questions
JuniorTheoryVery commonWhat is a signal, and what do SIGTERM, SIGKILL, SIGHUP and SIGSTOP do?
What is a signal, and what do SIGTERM, SIGKILL, SIGHUP and SIGSTOP do?
A signal is an async notification the kernel delivers to a process. SIGTERM asks it to exit and can be caught for cleanup; SIGKILL force-terminates it and cannot be caught, blocked, or ignored; SIGHUP means a terminal hangup and by convention tells daemons to reload config; SIGSTOP pauses a process (also uncatchable) and SIGCONT resumes it.
Common mistakes
- ✗Thinking
SIGKILLorSIGSTOPcan be caught or ignored by a handler - ✗Confusing
SIGTERM(graceful) withSIGKILL(forced) - ✗Reading
SIGSTOPas termination rather than a pausing signal
Follow-up questions
- →Which two signals can never be caught, blocked, or ignored, and why?
- →Why do many daemons reload their config on
SIGHUPrather than restart?
JuniorTheoryVery commonWhat is a process, and what do fork and exec do?
What is a process, and what do fork and exec do?
A process is a running instance of a program with its own PID, a parent PID (PPID), a private virtual address space, and a table of open file descriptors. fork clones the caller into a near-identical child using copy-on-write pages; exec then replaces that child's memory image with a new program while keeping the same PID.
Common mistakes
- ✗Thinking
forkandexecare one call rather than the clone-then-replace pair - ✗Believing
execstarts a new PID instead of reusing the caller's - ✗Assuming a child shares the parent's writable memory instead of copy-on-write
Follow-up questions
- →Why does copy-on-write make
forkcheap even for a large parent process? - →What does a child inherit from its parent across
forkbesides memory?
JuniorTheoryCommonWhat is a file descriptor, and what are fd 0, 1 and 2?
What is a file descriptor, and what are fd 0, 1 and 2?
A file descriptor is a small non-negative integer a process uses to refer to an open file, socket, or pipe — an index into its per-process table of open handles. By convention fd 0 is standard input, fd 1 is standard output, and fd 2 is standard error. Redirection and pipes just rewire these numbers, which is why 2>&1 sends stderr to wherever stdout points.
Common mistakes
- ✗Swapping the roles of fd 1 (stdout) and fd 2 (stderr)
- ✗Thinking a descriptor stores a path string rather than an index into a table
- ✗Believing descriptors are global rather than per-process
Follow-up questions
- →What does the redirection
2>&1actually do to the descriptor table? - →Why can a file deleted while an fd is still open keep consuming disk space?
JuniorTheoryCommonWhat do the Linux process states R, S, D, T and Z mean?
What do the Linux process states R, S, D, T and Z mean?
R is running or runnable (on a CPU or waiting for one). S is interruptible sleep — waiting for an event and wakeable by a signal. D is uninterruptible sleep, usually blocked in a kernel I/O call and not even killable until it returns. T is stopped by a signal like SIGSTOP. Z is a zombie — exited but not yet reaped by its parent.
Common mistakes
- ✗Confusing
D(uninterruptible sleep) with a normalSsleep you can signal - ✗Thinking a
Zzombie still runs and consumes CPU - ✗Reading
T(stopped) as terminated rather than paused by a signal
Follow-up questions
- →Why can a process in state
Dnot be killed even withSIGKILL? - →How does a
Zzombie differ from a process in stateT?
MiddleTheoryCommonWhat is a zombie process, who creates it, and how do you clear it?
What is a zombie process, who creates it, and how do you clear it?
A zombie is a process that has exited but whose parent has not yet wait()ed on it, so the kernel keeps a tiny entry holding just its PID and exit status. It is already dead — you cannot kill -9 a zombie. It clears when the parent reaps it (often after a SIGCHLD); if the parent never does, killing or ending the parent reparents nothing but lets init reap it.
Common mistakes
- ✗Trying to
kill -9a zombie, which is already dead and cannot be killed - ✗Thinking a zombie holds memory rather than just a PID and exit status
- ✗Blaming a runaway process instead of a parent that never reaps
Follow-up questions
- →Why does killing the parent let init eventually reap the zombie?
- →How is a zombie different from an orphan process?
MiddleTheoryOccasionalWhat is an orphan process, and what adopts and reaps it?
What is an orphan process, and what adopts and reaps it?
An orphan is a still-alive process whose parent has exited. The kernel reparents it to init (PID 1), which becomes its new parent and later wait()s on it when it exits, so an orphan does not become a zombie. That is why PID 1 must reap children — a naive container init that ignores SIGCHLD leaks zombies from its adopted orphans.
Common mistakes
- ✗Confusing an orphan (alive, reparented) with a zombie (dead, unreaped)
- ✗Thinking an orphan lingers forever instead of being adopted by init
- ✗Missing that PID 1 must reap
SIGCHLDor a container leaks zombies
Follow-up questions
- →Why does a container run better with a real init like
--initor tini? - →What happens to an orphan's PPID after the kernel reparents it?
MiddleDebuggingOccasionalA process in state D ignores kill -9 — diagnose why and what to do
A process in state D ignores kill -9 — diagnose why and what to do
D is uninterruptible sleep: the process is blocked inside a kernel call — here dd waiting on failing disk I/O. SIGKILL is queued but cannot be delivered until that syscall returns, so kill -9 does nothing while it hangs. You cannot force it dead; fix the underlying I/O (the sick device, an NFS mount, storage) so the call unblocks and it exits — otherwise reboot the host.
Common mistakes
- ✗Trying harder with
kill -9when aDprocess cannot receive it yet - ✗Mistaking uninterruptible sleep for a zombie or a caught-signal handler
- ✗Ignoring the real cause — stuck disk, NFS, or block-device I/O
Follow-up questions
- →How would you find which device or mount the process is blocked on?
- →Why does the kernel use an uninterruptible sleep for some I/O at all?
JuniorTheoryRareWhat is PATH, and how does the shell find which binary to run?
What is PATH, and how does the shell find which binary to run?
PATH is an environment variable holding a colon-separated list of directories. For a bare command like ls, the shell searches those directories left to right and runs the first matching executable, so order matters. A command with a slash (./app, /usr/bin/ls) skips the search entirely. which shows which one would win.
Common mistakes
- ✗Thinking the shell searches
PATHfor a command written with a slash - ✗Forgetting
PATHis scanned left to right, so order decides the winner - ✗Believing
PATHnames one directory rather than a colon-separated list
Follow-up questions
- →Why is putting
.at the front ofPATHa security risk? - →How do
which,typeand the shell's hash cache differ when resolving a command?
JuniorTheoryRareWhat is a syscall, and how does a program cross into the kernel?
What is a syscall, and how does a program cross into the kernel?
A syscall is the controlled entry point through which a user-mode program asks the kernel to do something privileged — read a file, open a socket, fork. The program can't touch hardware directly, so it triggers a trap (a special instruction like syscall) that switches the CPU to kernel mode, runs the handler, and returns the result to user mode.
Common mistakes
- ✗Thinking a syscall runs in user mode like an ordinary function call
- ✗Believing a program can reach hardware without going through the kernel
- ✗Missing the trap and CPU mode switch that a syscall performs
Follow-up questions
- →Why does a mode switch make a syscall more expensive than a plain call?
- →How does the C library
libcsit between your code and the raw syscall?