I'm trying to restart the same process right after the old one exits, but after few executions my program crashes. Valgrind is reporting invalid reads and writes related to the handler, but I'm having no luck with getting closer to a fix. The sample code shows only one process, but my goal is to have a few of these processes that restart themselves running at the same time.
std::function<void(int, const std::error_code&)> on_exit;
on_exit = [this, &on_exit](int exit, const std::error_code& ec_in) {
// error handling
client.wait();
client = bp::child(path_to_client, io_context, bp::on_exit=on_exit);
};
client = bp::child(path_to_client, io_context, bp::on_exit=on_exit);
io_context.run();
The client
, path_to_client
, and io_context
are all members of a class.
Removing the call to launch the new process inside the lambda fixes the valgrind errors.
on_exit
is a local function, but you capture it by reference. Fix it by making it live long enough, e.g. by using a member variable like client
instead.
Here's a self-contained demo program:
#include <boost/process.hpp>
#include <iostream>
namespace bp = boost::process;
struct ProgramX {
boost::asio::io_context io_context;
bp::child client;
unsigned remaining = 0;
std::function<void(int, std::error_code)> on_exit = [this](int exit, std::error_code ec) {
client.wait();
std::cout << "exit code " << exit << " (" << ec.message() << ")" << std::endl;
// error handling...
if (--remaining)
launch();
};
void launch() {
boost::filesystem::path path_to_client = "/bin/sleep";
std::vector<std::string> args = {"1"};
client = bp::child(path_to_client, args, io_context, bp::on_exit = on_exit);
}
void foo(unsigned how_many_runs) {
remaining = how_many_runs;
launch();
io_context.run();
}
};
int main() {
ProgramX x;
x.foo(5);
}
When trying things online, I noticed that... it didn't work as expected.
/bin/sleep
)Here's a side-by-side on my local machine¹:
So in all likelihood, you (also) need to update to Boost 1.82.0 sooner rather than later.
¹ note both say 108200 but you can see me switching the release tag for just the process submodule