1

I wrote a multi-platform C++ class that launches a user-specified child process, and lets the user communicate with the child process's stdin/stdout, wait for the child process to exit, and so on.

In the Unix/POSIX implementation of this class, I've just added a feature that lets the caller find out whether the child process's exit was due to an unhandled signal (i.e. a crash):

bool ChildProcessDataIO :: WaitForChildProcessToExit(bool & retDidChildProcessCrash)
{
  int status = 0;
  int pid = waitpid(_childPID, &status, 0);
  if (pid == _childPID)
  {
     retDidChildProcessCrash = WIFSIGNALED(status);
     return true;
  }
  else return false;  // error, couldn't get child process's status
}

... and now I'd like to add similar functionality to the Windows implementation, which currently looks like this:

bool ChildProcessDataIO :: WaitForChildProcessToExit(bool & retDidChildProcessCrash)
{
   bool ret = (WaitForSingleObject(_childProcess, INFINITE) == WAIT_OBJECT_0);
   if (ret) 
   {
      /* TODO:  somehow set (retDidChildProcessCrash) here */
   }
   return ret;
}

... but I haven't figured out how to set (retDidChildProcessCrash) to the appropriate value using the Win32 API.

Is there some way to do this, or do I just need to put a note in my documentation that this feature isn't currently implemented under Windows?

Jeremy Friesner
  • 70,199
  • 15
  • 131
  • 234

1 Answers1

3

Arrange for the child to communicate with the parent to indicate completion. A shared event would be one way. If the process terminates and the parent has not received notification of success then it can conclude that the child failed.

Another option might be to use the process exit code. Will be zero on success, assuming the child follows the usual conventions. And a crash will lead to an error code indicating the form of the crash, according to this question: Predictable exit code of crashed process in Windows?

This is less reliable though. A process might terminate because it had TerminateProcess called on it, with a zero exit code. So if you control both process the first approach is safer. If you don't control the child process then the exit code might be your best shot. There's not much else you can get from a process handle of a terminated process.

Community
  • 1
  • 1
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • The child process may be any arbitrary program, so I don't think I can depend on its co-operation. Checking the exit code might be good enough for my purposes, if there is no better approach. – Jeremy Friesner Aug 26 '15 at 20:39
  • I'm going with the exit-code solution: DWORD exitCode; if (GetExitCodeProcess(_childProcess, &exitCode)) retDidChildProcessCrash = ((exitCode & (0xC0000000)) != 0); – Jeremy Friesner Aug 26 '15 at 21:24
  • @JeremyFriesner: That's a pretty random solution, and it will be unreliable. Unless you write a debugger, you won't be able to get notified about unhandled exceptions. If this is not something you want to do, don't offer an implementation, that cannot reliably report, how a process terminated. – IInspectable Aug 27 '15 at 18:13
  • @IInspectable I included a note in the method's documentation documenting its shortcomings under Windows. The current implementation is good enough to serve my purpose, so I will use it until I am able to replace it with something better. – Jeremy Friesner Aug 27 '15 at 20:39