Sunday, 22 June 2014

Kill Parent Process

Months ago I wrote about the differens between Windows and Linux with regards to how they handle Processes and Threads. There's another important difference regarding processes, the Parent-Child relationship.

I think we can say this Parent Process - Child Process relation in Linux is strong. There are many ways to see a process tree, and I used to think that killing a parent process automatically kills its children. Well, this is partially true. If you start a process from the terminal and you kill the terminal, the child process will be also killed (unless you handle the SIGUP signal), but this is not so when the parent process is a normal process

No. If the parent is killed, children become children of the init process (that has the process id 1 and is launched as the first user process by the kernel).

In windows, the only way to see a process tree that is known to me is using Process Explorer, and definitely, killing the command line won't kill the processes started from it.

The thing is that lately, when developing in Windowns, I've come across the need of programmatically killing a main process and all its children. I know the PID of the parent process, but just killing it will leave its children alive and well. Of course you can go to the Task Manager and select the "Kill Process Tree" option, but as I've said, I need to do this programmatically. There's not any sort of Win32 API method like "KillProcessTree". Indeed, you don't even have an out of the box GetParentProcessId function. As explained here, you could create your own and use it along with a list of all processes in the system. Not an immediate solution, and seems like error prone as Windows will reuse PIDs as they are released.

"Alternatively, can someone alleviate my fear that the pid I'm passing might belong to another process after some time if the parent has died?"
Yes, the PID can be reused. Unlike UNIX, Windows does not maintain a strong parent-child relationship tree.

Hopefully, there's a much more simple solution, thanks to one of those powerful Windows command line tools that most people seem unaware of (driverquery is another one that comes to mind).

TASKKILL /F /T /PID $pid

You pass it the PID of a process et voila! the process will be killed along with all its children. A nice Process massacre.

It seems like it's also more simple than it initially seemed to get the PPID of a given PID, you can use the almighty (and barely known) WMI console:

wmic process where (processid=PROCID_HERE) get parentprocessid

I've mentioned above that Windows will reuse Process IDs once the corresponding process ceases to exist. This seems quite weird to me, I think it would make more sense to follow the Linux approach (from here and here

As new processes fork in, PIDs will increase to a system-dependent limit and then wrap around. The kernel will not reuse a PID before this wrap-around happens.

Under Unix, process IDs are usually allocated on a sequential basis, beginning at 0 and rising to a maximum value which varies from system to system. Once this limit is reached, allocation restarts at zero and again increases. However, for this and subsequent passes any PIDs still assigned to processes are skipped.

No comments:

Post a Comment