Jump to content
  • Advertisement
Sign in to follow this  
spraff

Reliably killing child processes in a crash

This topic is 3608 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi everyone. When my application crashes, any threads it created will be destroyed, but if I have created processes they will continue to live independently, right? I know how to capture SIGINT etc and can kill my spawn there, but that doesn't cover all cases (after a SIGSEGV for example, program behaviour is formally undefined, AFAIK). Is there a general-purpose reliable method for cleaning up child processes? Cross-platform solutions would be nice :) Thanks

Share this post


Link to post
Share on other sites
Advertisement
One way to accomplish this is with a keep-alive message. Basically, once every 10 seconds the parent process sends each of its children a message, to let them know it is still alive, and if no message is received for 20 seconds, each child process terminates itself.

Share this post


Link to post
Share on other sites
Quote:
Original post by spraff
When my application crashes, any threads it created will be destroyed, but if I have created processes they will continue to live independently, right?

I know how to capture SIGINT etc and can kill my spawn there, but that doesn't cover all cases (after a SIGSEGV for example, program behaviour is formally undefined, AFAIK).

You have two competing standards, here, I believe. I can't be sure right now because my copy of the C++ standard is at work.

But POSIX says:
Quote:

The behavior of a process is undefined after it ignores a SIGFPE, SIGILL, SIGSEGV, or SIGBUS signal that was not generated by kill(), sigqueue(), or raise().


I take this to mean that you may install a handler for SIGSEGV.

But in any handler you may only call async-signal-safe functions (a bit further down on that last link). Fortunately kill() is such a function.

It is only after the handler has returned that the behaviour is undefined (according to POSIX).

Quote:
Is there a general-purpose reliable method for cleaning up child processes? Cross-platform solutions would be nice :)


AFAIK, Windows has no formal notion of "child processes", so unless there's a canned wrapper available, things will be somewhat different. I'm intrigued by other peoples' responses to this because I'll be porting a library to Windows soon that is designed to spawn and communicate with auxiliary processes.

EDIT: perhaps use _set_se_translator on Windows?

Share this post


Link to post
Share on other sites
If you want a last-resort exception handler in windows, you can install one using "SetUnhandledExceptionFilter". If you want a first-resort exception handler in windows (that will also catch C++ exceptions, so you need to filter based on exception type), you can install one using "AddVectoredExceptionHandler". In MSVC, you can also use the __try / __except keywords to install scoped exception handlers.

You can find most* child processes using "CreateToolhelp32Snapshot" and "Process32First" / "Process32Next" to iterate over all processes and form a relationship tree based on process IDs (using GetCurrentProcessID to find the parent ID to use as a root), then use "OpenProcess" to turn the ID into a handle and then "TerminateProcess" to kill it.

* Most but not all because windows does not keep information about a process after it's handles are closed, so if you have process A create process B, then process B create process C, then process B closes, there won't be an easy way to identify that process C was indirectly spawned by process A.

Share this post


Link to post
Share on other sites
Exceptions won't do it, not every crash raises an exception.

Here's a question for the Guru's, will a modern OS ever terminate a process without sending it a signal first?

A horribly hacky way to do it would be to wrap process creation in a function that synchronises this with some database (heck, the filesystem would do) and you could then have a simple (hence verifiable) process which monitored lost PIDs.

Keepalive messages seem a bit dirty to me. I was thinking the parent process could hold the STDIN file handle to the child, and crashing would mean that file handle gets closed. The child could detect this although I want to allow third-party plug-ins which might use STDIN differently.

Share this post


Link to post
Share on other sites
Quote:
Original post by spraff
Here's a question for the Guru's, will a modern OS ever terminate a process without sending it a signal first?
AFAIK Windows XP (no idea whether Vista changes this) can terminate your process without sending it any signal whatsoever.

Quote:
Keepalive messages seem a bit dirty to me. I was thinking the parent process could hold the STDIN file handle to the child, and crashing would mean that file handle gets closed. The child could detect this although I want to allow third-party plug-ins which might use STDIN differently.
That approach works, but again, only on *nix, where you have signals anyway - so a bit redundant.

Share this post


Link to post
Share on other sites
Quote:
Original post by spraff
Exceptions won't do it, not every crash raises an exception.[...]
Can you give any examples? I don't think TerminateProcess raises an exception, but that isn't a crash.

The best alternative I can think of is a 'launcher' process that creates the base process and regularly iterates through all processes to find children. Once it detects that the base process isn't running, it can close all children.

Share this post


Link to post
Share on other sites
Quote:
Original post by spraff
Seg faults don't throw exceptions, you need signals.
The same point of confusion keeps coming up here: Extarius is talking about Windows, while you are talking about unix. You asked for a portable solution, and portable implies Windows as well.

Share this post


Link to post
Share on other sites
Quote:
Original post by swiftcoder
Quote:
Original post by spraff
Seg faults don't throw exceptions, you need signals.
The same point of confusion keeps coming up here: Extarius is talking about Windows, while you are talking about unix. You asked for a portable solution, and portable implies Windows as well.
I believed that to be the problem, which is why I asked for clarification. Segmentation faults are known as "access violations" on windows, and do indeed throw an exception (though not the C++ kind).

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!