boost::process:: child::wait() on Linux ignores a zombie process
- Dominant language
- C++
- Stars
- 145
- Forks
- 151
- PR merge metrics
- No merged PRs in 30d
Description
Reproducible in the following example:
```
#include
int main()
{
namespace bp = boost::process;
std::string appCommand = "sleep 50";
bp::child childProcess(appCommand);
int pid = childProcess.id();
printf("childProcess.running()=%d\n", childProcess.running());
childProcess.terminate();
childProcess.wait();
printf("childProcess.running()=%d\n", childProcess.running());
// kill 0 returns 0 if process is running
bool isRunning = (::kill(pid, 0) == 0);
printf("isRunning=%d\n", isRunning);
}
```
output on my machine is:
```
childProcess.running()=1
childProcess.running()=0
(kill 0 23764): isRunning=1
```
The program will print ```isRunning=1``` at its end, meaning that the process is still running. Pausing at that point with debugger and checking ```ps -ax``` will also show that the process is a zombie.
After some investigation, faulty code seem to be in ```include/boost/process/detail/child_decl.hpp```:
```
bool _exited()
{
return _terminated || !::boost::process::detail::api::is_running(_exit_status->load());
};
void terminate(std::error_code & ec) noexcept
{
if (valid() && running(ec) && !ec)
boost::process::detail::api::terminate(_child_handle, ec);
if (!ec)
_terminated = true;
}
void wait(std::error_code & ec) noexcept
{
if (!_exited() && valid())
{
int exit_code = 0;
boost::process::detail::api::wait(_child_handle, exit_code, ec);
if (!ec)
_exit_status->store(exit_code);
}
}
```
```terminate()``` marks ``` _terminated = true```, and ```wait()``` never calls its main logic because ```_exited()``` evaluates true.
A possible solution would be to perform a blocking wait at the end of ```boost::process::detail::api::terminate()```, because ATM it waits with ```WNOHANG```.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.