CreateProcess such that child process is killed when parent is killed?

浪尽此生 提交于 2019-11-30 11:33:37
wilx

Using jobs as Neil says is IMHO the best way. You can make the child processes get killed when the job owning process dies by setting JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE on the job object using SetInformationJobObject(). The job object handle will be closed when your parent process exits/dies. For this to work it is essential that the job handle is not inherited by the child processes. If you want to track also the grand-child processes then you will have to create your child processes suspended, add them to your job object and only then let them run.

The best you can do is to put both processes in the same job, so that killing the job kills both processes.

Do you need the child process to be killed, or merely detect the parent process exit so it can terminate cleanly? The parent process can create an inheritable handle to itself, which the child can then pass to WaitForMultipleObjects(Ex) along with its own objects.

If the child process isn't written specifically for this, you could attach its stdin to a pipe, the other end of which is held by the parent process. If the parent dies, the pipe is automatically closed.

This closely parallels the Unix behavior, in which a child isn't killed when its parent dies, it generally exits in response to SIGHUP (but it can handle that signal and implement any behavior). On Linux, the parent PID of an orphan is changed to 1 (init).

I suppose DEBUG_PROCESS or DEBUG_ONLY_THIS_PROCESS would do that as an almost-accidental side-effect. Windows doesn't create processes in a tree the way Unix-like systems do though.

A different approach

Not useful in all situations, however I had one particular scenario where an application was controlling a child process completely. For communication & API interception, a DLL injection was required so a DLL is running in the actual child processes to report back to the parent.

Note: Now, this is not for the creativity award. Background here is: An application that needed to be wrapped, however that was a legacy application and could neither be modified, nor rewritten in a satisfying manner. We needed to keep this system running, while still intercepting outputs from it.

Also, the child process was poorly written, launching itself again immediately and then terminating, so the parent process is actually not our main application.

If you control the child processes and have an injected DLL anyway, you can extend this DLL by monitoring the parent process to check if it is running. If not, ExitProcess.

If you don't need a DLL in the child process, the other solutions are most likely far better.


You can transfer the parentProcessID through, for instance, a registry key that you use by your application already. Or you can pass a commandline, if this doesn't break the child process.

This has to run in its own thread. My DLL had two threads: This code here and the controlling & communication code.

DLL

bool IsProcessRunning(HANDLE hProcess)
{
    DWORD exitCode;
    GetExitCodeProcess(hProcess, &exitCode);
    return exitCode == STILL_ACTIVE;
}

bool WINAPI DllMain(HINSTANCE hInstDll, DWORD fdwReason, LPVOID lpvReserved)
{
    if (fdwReason == DLL_PROCESS_ATTACH)
    {
        int parentProcessID = [...]

        HANDLE parentProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, TRUE, parentProcessID);
        while (IsProcessRunning(parentHandle)) Sleep(100);
        ExitProcess(0);
    }

    return true;
}

Dont know about windows, but this will work on linux: prctl(PR_SET_PDEATHSIG, SIGHUP);

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!