The Big Picture: Closing the Restaurant
Every process ends. It might close politely at the end of the day (normal exit), be shut by the landlord (killed), or burn down (crash). Whichever way it ends, Windows has the same cleanup crew: it takes back the memory, closes the open files, and tells anyone who is interested.
NORMAL EXIT ABNORMAL (killed) CRASH (exception)
program says someone else says program does something
"I'm done" "stop now" illegal and is stopped
\ | /
+-----------------+------------------------+
|
v
WINDOWS CLEANUP
(free memory, close handles, record exit code)
3.1 Normal Exit
What it is: The program finishes its job and asks Windows to end it. Windows has a function for this: ExitProcess. Most programs call it for you: when your main function returns, the language's runtime calls ExitProcess.
Things a program usually does first:
- Saves your files.
- Closes its windows.
- Lets each DLL do its own cleanup (the DLLs get a "process is ending" notice).
The exit code. A process ends with a number called its exit code. By long tradition:
| Exit code | Usual meaning |
|---|---|
0 | Success, everything went fine |
| Any other number | Some kind of error or special result; the program's author decides what it means |
In Command Prompt, the last exit code is in %ERRORLEVEL%. Try this: cmd /c exit 5 then echo %ERRORLEVEL% prints 5. In PowerShell the same idea is the $LASTEXITCODE variable (for programs you ran) and $? (true or false for the last command).
While a process is running, its exit code is a special value (259, known as STILL_ACTIVE), meaning "not finished yet".
3.2 Abnormal Termination
What it is: The process is stopped by someone else, without being given the chance to tidy up properly. The program did not choose to end.
| Way | What happens |
|---|---|
| End task in Task Manager | First tries to close the window politely; if that fails, kills it |
taskkill /PID 1234 | Asks the program to close (like clicking the X) |
taskkill /PID 1234 /F | Forces it: Windows ends it at once (TerminateProcess) |
Stop-Process -Id 1234 | PowerShell's version; it also terminates forcefully |
| Shutdown or sign-out | Windows asks each program to close, then force-stops those that do not answer |
The force option uses the Windows function TerminateProcess. The program gets no chance to save its data or run cleanup code. Unsaved work is lost. That is why you should try the polite way first.
You normally need rights to end a process. You can end your own programs. To end services or other users' processes you need to run as Administrator, and some protected system processes cannot be ended even by an admin.
3.3 Crash / Exception
What it is: An exception is the CPU saying "this instruction is illegal". Examples: reading memory that does not exist (an access violation), dividing by zero, or running a broken instruction. The CPU raises a fault (a type of error trap, see the interrupts section of Chapter 4). Windows catches it and checks whether the program planned for it.
Illegal action
|
v
CPU fault --> Windows looks for a handler in the program
| |
handler found none found
| |
program recovers process is terminated
(error report may appear)
Programs can include code to handle exceptions (called structured exception handling on Windows; in many languages it looks like try ... catch). If no code handles it, Windows ends the process. You might see a window like "Application has stopped working", and Windows may write a crash dump file (a snapshot of memory) so a developer can investigate. Crash exit codes look like big numbers such as 0xC0000005 (access violation).
Why isolation (Section 1.4) helps: when one process crashes, the others are untouched. Only the kernel crashing takes down the whole PC.
3.4 Cleanup (Memory, Handles, Files)
What it is: When a process dies, Windows does a full cleanup. The process itself does not have to do it, which is why leaks inside one process do not last forever.
| Resource | What Windows does |
|---|---|
| Threads | All stopped |
| Virtual memory | The whole address space is released; the RAM goes back to the free pool (Chapter 3) |
| Handles | Every handle in the process's handle table is closed (Section 5) |
| Open files | Closed, so other programs can use them again (the "file in use" message goes away) |
| Windows (the GUI kind) | Destroyed |
| Locks and events | Released; other processes waiting for them are woken up |
| The EPROCESS | Kept for a while, see below |
Not everything is cleaned automatically. Things the process created in the outside world may stay: files it wrote, registry entries it made, child processes it started (they keep running, Section 10), and shared memory that other processes still use.
The exit code is stored in the kernel's record. Anyone who holds a handle to the process can ask for it (the function is GetExitCodeProcess).
3.5 Zombie Processes
What it is: On Linux, a zombie is a dead process whose entry is still in the table because its parent has not read its result yet. Windows has no process called "zombie" and no wait() call that forces it, but a similar thing can happen.
On Windows the dead process's kernel record lives on as long as anyone has a handle to it. If a parent (or any program) starts a process and never closes the handle, the process record stays in kernel memory even though the program is long gone. It uses almost no CPU or RAM, but it is a leak.
Process has exited ---> its code, memory, threads are gone
|
v
Small EPROCESS record still exists
because another program holds a handle
|
holder closes handle ---> record is finally freed
How you may notice this:
- A process vanishes from Task Manager (its PID is no longer listed as running), yet handle counts of some other program keep growing.
- Tools like Sysinternals Process Explorer (free from Microsoft, optional) can show these leftover processes.
A related effect: because the PID can be reused after the record is freed, Windows keeps the PID reserved while any handle is open, which prevents mistakes such as "killing the wrong process by an old PID".
The fix is simple: the code that started the process should call CloseHandle on the process handle (and the thread handle) when it is done with them. Closing the program that leaks also releases everything.
Summary
| Term | Plain meaning |
|---|---|
| ExitProcess | The program ends itself politely |
| Exit code | A number left behind; 0 usually means success |
| TerminateProcess | Force-kill: no cleanup by the program |
taskkill / /F | Command-line ending; /F means force |
| Exception | CPU or program fault; unhandled means the process dies |
| Crash dump | Snapshot of memory saved after a crash |
| Cleanup | Windows frees memory, handles and files; children and written files stay |
| Zombie-like leftover | Dead process record kept alive because a handle is still open |