0

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?
Germán Diago
  • 7,473
  • 1
  • 36
  • 59

2 Answers2

0

Just looking at your code, the first thing that strikes me is that you don't actually test the "ec" variable that says whether execute() succeeded or not until after you call wait_for_exit(). If you're calling wait_for_exit() with an invalid child process, it's quite understandable that it would crash.

Start by checking "ec" before calling wait_for_exit().

DavidK
  • 3,929
  • 1
  • 19
  • 26
  • 1
    How can I check `ec` if I cannot wait for the process to finish? I cannot. Chicken-egg problem or I do not understand well the API. – Germán Diago Jan 29 '16 at 12:12
  • The problem is that `execve` is going to launch the process, so I must wait for the process to finish to get a proper `ec`. But when I wait, it crashes. – Germán Diago Jan 29 '16 at 12:13
  • I tried as your suggestion with no luck: you could take a look to the edited code in the question for any insights. – Germán Diago Jan 29 '16 at 12:20
  • That isn't my understanding of the API: the error code returned by execute() tells you whether it was possible to start the child process at all, not whether the child process itself was successful. As soon as the process is started without any OS errors, execute() can return with ec == 0, which is why I suggested you need to test that before calling wait_for_exit(). Looking at the code you posted, it still seems to me that the most likely reason for a crash is calling wait_for_exit() with an invalid child process object. Can you use a debugger to check that p.pid is valid? – DavidK Jan 29 '16 at 12:35
  • Yes, I agree, but even after the correction, it is not working yet :( – Germán Diago Jan 29 '16 at 12:42
  • Did you try my debugging suggestion, to look at p.pid before waitforpid()? – DavidK Jan 29 '16 at 12:52
  • I found the problem. I will reply now. None of the things we were saying actually. – Germán Diago Jan 29 '16 at 14:56
0

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.

Germán Diago
  • 7,473
  • 1
  • 36
  • 59