Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[cdt-dev] An FYI on starter.cxx


Hi!

I found a case where on Windows2000 calling Spawner::destroy() would end up hanging the thread calling it. The case was a little confusing but basically a launcher was spawning a windows app that caught CTRL_C_EVENT and ignored. That meant that the TerminateProcess call was the thing actually killing the process. Quoting from the windows docs on TerminateProcess:

Use it only in extreme circumstances. The state of global data maintained by dynamic-link libraries (DLLs) may be compromised if TerminateProcess is used rather than ExitProcess.

The lockup happened when Spawner.destroy() went to close stderr. iostreams::SpawnerInputStream_close0 hung under CloseHandle(). The handles were all correct, nothing had been corrupted, I can only assume that what the quote above warned about actually happened.

To fix my case, I added a GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, 0 ) to the existing CTRL_C_EVENT in starter.exe to send a signal that the app was not catching and ignoring. The lockup went away. Clearly this would not be a fix if the spawned application were also catching CTRL_BREAK_EVENT, so it's not a generic solution.

Probably the "right" fix is a two stage shutdown where you try a signal first, if that works you know you can close the file descriptors safely. If it does not, you expressly ask for TerminateProcess and shut the filedescriptors with an awareness that the call to Spawner*Stream.close() may hang. A return from Spawner.raise(x,TERM) indicating if TerminateProcess had to be used would also work.

I'm not advocating all that work -- it's surely not worth it unless someone actually comes up with the case. Just an FYI.

Thanks,
-Chris

Back to the top