Microsoft KB Archive/270117

{|
 * width="100%"|

PRB: TerminateProcess Does Not Terminate the Target Process

 * }

Q270117

-

The information in this article applies to:


 * Microsoft Win32 Application Programming Interface (API), included with:
 * Microsoft Windows NT Server version 4.0
 * Microsoft Windows NT Workstation version 4.0
 * Microsoft Windows 2000 Server
 * Microsoft Windows 2000 Professional

-

SYMPTOMS
A process continues to exist after a call to the TerminateProcess function on that process has successfully returned.

CAUSE
When there is a request to terminate a process through the TerminateProcess function, Windows stops all the user-mode activity of the target process. However, the target process cannot actually exit until all kernel-mode activity specific to that process is complete. This means that the target process continues to exist until all of its threads have left kernel-mode and all pending IO has been canceled.

This situation occurs as the result of a device driver not releasing a thread or not canceling IO. The process continues to exist until the IO completes and all threads in the process are released from kernel mode.

RESOLUTION
Device drivers should be written such that they meet the following criteria:


 * They have a Cancel Routine and properly cancel any IO when requested. See the relevant Windows NT DDK for more information on Cancel Routines.
 * They never keep an application-owned thread longer than is necessary.

STATUS
This behavior is by design.

MORE INFORMATION
A process that has been terminated will not run further user-mode code. However, the process can't exit until all kernel-mode activity for that process is completed. To do otherwise would risk causing blue-screen faults when a driver might not expect the application to be gone. Several very important implications are that handles that are owned by that process won't be closed, memory won't be released, and modules that are loaded by the process won't be unloaded until the process actually exits.

To track down the specific device driver that is cause this behavior requires kernel debugging; either by using a Memory.dmp or by live debugging. Note that this article is not about kernel debugging; however, following are the basic steps. The individual kernel debugger commands are documented in the relevant Windows NT DDKs:


 * 1) Locate the process ID of the process that has been terminated. Use !process 0 0 if the process ID is not already known.
 * 2) Use !process id 7 to get extensive information about that process. If there are threads in kernel mode or pending IRPs, they will be listed.
 * 3) Use !irp irp to display more information about individual IRPs that are still pending. This information should indicate which driver each IRP is pending against.
 * 4) Use !thread thread to display more information about a particular thread. If the thread is running in kernel mode, there should be enough information in the stack trace to determine which driver it is currently running in.

Contact the driver manufacturer for more information.