Process exit on Windows and Linux



  • From the MSDN page on ExitProcess :

    Exiting a process does not cause child processes to be terminated.

    Who designed this shitty operating system?!

    For reference to get the sane behavior on termination of a child process that might have made further children you have to create a 'job object', create processes suspended, add them to the job object, resume the processes, and then kill the job object later. Which kills processes as if TerminateProcess were called instead of a clean exit, and if the child process wants to make its own job objects you're fucked because they /can't be nested/ up until windows 8, and even then there are some weird requirements on what you can do with nested job objects.

    Suspicion: C and C++ are much more popular in the unix world because the POSIX/Linux APIs aren't nightmare hellstews like the windows API is.


  • Impossible Mission Players - A

    Huh. TMYK.


  • SockDev

    TR undefined is you think a function called ExitProcess (singular!) should exit processes plural.



  • Hmm this might be misdirected. From reading around, apparently parent process exit doesn't guarantee child exit on UNIX either.

    All operating systems suck.

    (There are slightly better solutions in UNIX-land, though. "PR_SET_PDEATHSIG" is the relevant option, lets you say "When my parent dies send me this signal". Also a better equivalent of job objects and some other cute portable solutions).


  • Impossible Mission Players - A

    @jmp said:

    "When my parent dies send me this signalgreeting card"

    😒



  • @RaceProUK said:

    TR undefined is you think a function called ExitProcess (singular!) should exit processes plural.

    "I don't understand why I'm getting this memory leak; I'm definitely deleting everything"
    "Ah, here's your problem. You're only deleting the root node of the tree, you have to traverse the entire thing and delete every node yourself".


  • SockDev

    Right, so you've completely ignored the fact it's ExitProcess SINGULAR. As in it exits ONE process. Not two, not five, not twenty. ONE.



  • And "delete a;" doesn't say "delete a and also everything that has a child relationship with a;", but if a's destructor doesn't delete its children it's probably a mistake.


  • SockDev

    And that's different from ExitProcess how?

    Face it, all you're doing here is "This function does what it's designed to do, not what I want it to! WAH!".



  • @RaceProUK said:

    And that's different from ExitProcess how?

    Err... it isn't? I assume that's intended to be rhetorical and/or socratic, but I don't see the difference. When you destroy things, their children should go with them.

    @RaceProUK said:

    Face it, all you're doing here is "This function does what it's designed to do, not what I want it to! WAH!".

    How dare I be upset that because of API design decisions that look like a mistake to me there's no reliable way to kill an entire process tree in Windows!


  • SockDev

    @jmp said:

    When you destroy things, their children should go with them.

    It's clear you don't get how this works.

    When you delete a;, a's destructor cleans up a's children.
    When you ExitProcess, the process's exit handler cleans up its children.

    So yes, you're throwing a hissy fit because the API is behaving exactly the way it's documented, instead of somehow being clairvoyant enough to guess what you want.


  • Discourse touched me in a no-no place

    @RaceProUK said:

    TR undefined is you think a function called ExitProcess (singular!) should exit processes plural.

    If you want to kill child process when the parent dies, there's other ways to do it--send a message, trip a shared semaphore, etc.



  • You seem to be taking this somewhat personally...

    I'm modeling the "process' exit handler" here as being the stuff that runs after process termination and frees memory it allocated but never released, releases handles it never got around to releasing, etc.. I would have expected that catch-all handler to do all the relevant destructory things, like cleaning up children. Obviously it isn't, possibly because the code killing it (which I didn't write, to forestall that particular criticism) is calling TerminateProcess and that kills it hard. AFAICT the only way to actually get this code I don't control to exit cleanly is to start a remote thread in it and call ExitProcess from there, which seems mighty hacky.

    Obviously the API is behaving the way it's documented, I just think the way it's documented to behave is not how it should behave.

    I should be clearer about problem space, maybe. Program A is under my control, it starts arbitrary other programs. One such program is cmd running a batch file that then starts program C, not under my control. Program A occasionally wants to kill its children, and when it does so I don't necessarily know whether or how many children it's got, and the entire tree has to go. And doing that in Windows is a) a giant pain and b) unreliable, because the job-object solution doesn't work if children want to make job objects, and the walk-the-process-tree solution has race conditions.


  • SockDev

    Exactly. After all, who better to clean up a process's children than the process that spawned them?


  • SockDev

    @jmp said:

    I'm modeling the "process' exit handler" here as being the stuff that runs after process termination

    And therein lies your error; the exit handler runs before process termination.

    @jmp said:

    Obviously the API is behaving the way it's documented, I just think the way it's documented to behave is not how it should behave.

    So use an API that does behave the way you want.

    @jmp said:

    Program A occasionally wants to kill its children, and when it does so I don't necessarily know whether or how many children it's got

    Then Process A is designed badly, and needs a rethink.



  • @jmp said:

    You seem to be taking this somewhat personally...

    Here we go again...?



  • @RaceProUK said:

    And therein lies your error; the exit handler runs before process termination.

    Uh, if you call TerminateProcess() on something it still releases all memory it has allocated.

    @RaceProUK said:

    So use an API that does behave the way you want.

    There isn't one.

    @RaceProUK said:

    Then Process A is designed badly, and needs a rethink.

    That wasn't clear, sorry; process A doesn't know if any of the children it has started have child processes themselves. That is, if A starts B, A doesn't know if B has child C. A is closer to a shell here than a system that can fully specify all behaviours of children.

    Programs that can start arbitrary children can't possibly know if those children themselves have children.


  • SockDev

    @tar said:

    Here we go again

    On my own,
    Going down the only road I'll ever know.
    Like a drifter, I was born to walk alone.
    And I've made up my mind, I ain't wasting no more time…

    πŸ˜„


  • SockDev

    @jmp said:

    Uh, if you call TerminateProcess() on something it still releases all memory it has allocated.

    Wait, I thought you were calling ExitProcess? If you're calling TerminateProcess, no wonder you're hitting issues; TerminateProcess kills the process immediately, bypassing the exit handler entirely, and with absolutely no consideration for unflushed buffers and other stuff.



  • Yes, sorry, I haven't been very clear here. I was quoting the ExitProcess MSDN entry because I was surprised that normal-process-exit doesn't result in children dying, and it describes normal process exit.

    I didn't actually write the code, keep in mind, I'm just coming in later after the guy who originally wrote it quit and am trying to get it to work.

    Looking around on the wob the only solution I can find for cleanly exiting arbitrary child processes is this one, which is basically "Call CreateRemoteThread() to make that process call ExitProcess". Ugly.


Log in to reply
 

Looks like your connection to What the Daily WTF? was lost, please wait while we try to reconnect.