Search code examples
c++macosboostpidboost-process

Boost.Process wait_for_exit(child): crash?


I am using version 0.5 of Boost.Process. Documentation can be found here. I am using Mac OS X Yosemite.

My problem: I am launching a compilation as a child process. I want to wait for the process to finish.

When my child process compiles correctly, everything is ok.

But when my child process does not compile, my code seems to crash when calling boost::process::wait_for_exit.

My user code looks like this:

EDIT: Code has been edited to match latest, more correct version (still does not work).

s::error_code ec{};
bp::child child = bp::execute(bpi::set_args(compilationCommand),
              bpi::bind_stderr(outErrLog_),
              bpi::bind_stdout(outErrLog_),
              bpi::inherit_env(),
              bpi::set_on_error(ec));

bool compilationSuccessful = true;

if (!ec) {
    s::error_code ec2;
    bp::wait_for_exit(child, ec2);
  if (ec2)
    compilationSuccessful = false;
}

The internal implementation of bp::wait_for_exit:

template <class Process>
inline int wait_for_exit(const Process &p, boost::system::error_code &ec)
{ 
   pid_t ret;
   int status;
   do
   {
     ret = ::waitpid(p.pid, &status, 0); 
   } while ((ret == -1 && errno == EINTR) || (ret != -1 && !WIFEXITED(status)));
   if (ret == -1) {
       BOOST_PROCESS_RETURN_LAST_SYSTEM_ERROR("waitpid(2) failed");
   }
   else
       ec.clear();
   return status;
}

The code after ::waitpidis never reached when my compilation command fails. The error shown is: "child has exited; pid: xxxx; uid: yyy; exit value: 1".

Questions:

  1. Is this a bug or I am misusing boost::process::wait_for_exit.
  2. Any workaround for avoiding the crash I am getting that is portable?

Solution

  • So the problem was that Boost.Test modifies the signals stack in some way.

    This signal stack modification has interactions with Boost.Process and code cannot be reliably tested, at least in the default Boost.Test configuration.

    I rewrote the tests with a normal main and some functions and it did the job.