ObjectExplorer icon indicating copy to clipboard operation
ObjectExplorer copied to clipboard

Missing zombie at some point

Open lobeg25 opened this issue 2 years ago • 2 comments

I might have found a bug in a case that is maybe a corner case.

I am investigating a problem in our tests where a unit test launches an arbitrary executable (i used ping.exe, but works with other exe), waits for it to complete and then calls a function that ensures that we are not able to get a handle on this process again (i.e. we ensure there is no zombie, hence the name of the function :) WaitUntilProcessAndItsZombieAreDead). Everything worked fine with that but we changed something in the way we call the unittest and it broke, i.e. a zombie now remains... That's it for context.

So debugging all that, I discovered your tool. Previously I used RAMMap to detect zombies.

Here is the problem I got: Please note: I have a debugger attached to my unit test executable, in case it changes something. My code does that:

  • Calls CreateProcess to launch ping,exe
  • Waits for the process to be signaled: BOOST_REQUIRE( WaitForSingleObject( pi.hProcess, INFINITE ) == WAIT_OBJECT_0 );
  • Closes the handles on the thread and process: BOOST_REQUIRE( CloseHandle( pi.hThread ) != 0 ); BOOST_REQUIRE( CloseHandle( pi.hProcess ) != 0 ); After closing the process handle, we do not see ping.exe in the zombie processes in ObjExp.exe, which seems reasonable to me, but RAMMap, after a refresh, still shows the process, as a zombie (0K private memory)...
  • Then we call OpenProcess using the pid of ping.exe and we successfully get a handle on it, which would indicate that the process was still existing somewhere, as a zombie.
  • At this moment, if I refresh ObjExp.exe, the zombie reappears from the... dead? :)

I don't know why, but it seems the process was hiding somewhere ObjExp.exe does not find it. Maybe linked to the debugger? If I get time, I could try it without the debugger if it can help.

I know, maybe what I try to do with WaitUntilProcessAndItsZombieAreDead is not that useful but that's another question ;)

lobeg25 avatar Oct 20 '23 19:10 lobeg25

Well, ObjExp is not perfect here :) The way it works is by finding handles to processes that are dead. However, even if there are zero handles, the object may still exist as a zombie if there is a kernel reference (rare, but possible). Once you opened ping for the second time, a handle was created, so ObjExp was able to find it and see it points to a dead process.

zodiacon avatar Oct 20 '23 19:10 zodiacon

Ok, thanks for the explanation! I forgot to consider kernel references. So, corner case here. Could explain some strange situations that I witnessed in the past. Could maybe also explain the issue we are tracking in our code. We observe that if stdout is piped, the zombie stays alive and if it is not piped, it dies as we would expect.

lobeg25 avatar Oct 20 '23 20:10 lobeg25