Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

boost::process::v2 subprocess does not get a signal when calling request_exit

I have a setup where my integration test is calling up a subprocess (the actual process that should be tested).

I also want to test the de-init behaviour, so I want to gracefully close the subprocess in that test.

I spawn the subprocess with:

auto process(ctx, "process.exe", {"-f", "config.ini"});

Later on I call:

process.request_exit();
process.wait();

However, the subprocess never closes.

For simple testing I added the following signal handler for my main process:

void signal_handler(int signal_num)
{
std::exit(signal_num);
}

int main()
{
std::signal(SIGTERM, signal_handler);

...
}

I am working on a windows machine. Am I missing something?

like image 326
honigkuchen Avatar asked Sep 30 '25 09:09

honigkuchen


1 Answers

First, I installed windows. Then Boost 1.86. Then I went into libs\process\test\v2 and did ..\..\..\..\b2.exe to check that the test run. They do.

In fact the request_exit test case works as well:

enter image description here

So what's different about their setup?

BOOST_AUTO_TEST_CASE(request_exit)
{
  asio::io_context ctx;

  using boost::unit_test::framework::master_test_suite;
  const auto pth =  master_test_suite().argv[1];


  bpv::process proc(ctx, pth, {"sigterm"}
#if defined(BOOST_PROCESS_V2_WINDOWS)
    , bpv::windows::show_window_minimized_not_active
    , bpv::windows::create_new_console
#endif
    );
  BOOST_CHECK(proc.running());
  std::this_thread::sleep_for(std::chrono::milliseconds(250));
  proc.request_exit();
  proc.wait();
  BOOST_CHECK_EQUAL(proc.exit_code() & ~SIGTERM, 0);
}

Noteworthy: the process creation flags. Let's add those:

#define _WIN32_WINNT 0x0601
#include <boost/process/v2/process.hpp>
#include <iostream>
#include <thread>

#if defined(BOOST_PROCESS_V2_WINDOWS)
#include <boost/process/v2/windows/creation_flags.hpp>
#include <boost/process/v2/windows/show_window.hpp>
#endif

using namespace std::chrono_literals;
namespace bp = boost::process::v2;
namespace asio = boost::asio;

int main(int, char** argv) {
    static auto debug = [=](auto const&... m) {
        ((std::clog << std::setw(14) << std::quoted(argv[0]) << ": ") << ... << m) << std::endl;
    };
    debug("Working directory: ", boost::filesystem::current_path().string());

    debug("Starting");
    auto process = bp::process(asio::system_executor{}, "process.exe", {"-f", "config.ini"}
#if defined(BOOST_PROCESS_V2_WINDOWS)
    , bp::windows::show_window_minimized_not_active
    , bp::windows::create_new_console
#endif
 );

    debug("Started");
    std::this_thread::sleep_for(3s);

    debug("Requesting exit");
    process.request_exit();

    debug("Waiting for exit");
    process.wait();

    debug("Child exit: ", process.exit_code());
}

With the Process.exe vain.cpp:

#define _WIN32_WINNT 0x0601
#include <iostream>
#include <iomanip>
#include <boost/asio.hpp>
namespace asio = boost::asio;

int main(int, char** argv) {
    asio::io_context ioc(1);
    static auto debug = [=](auto const&... m) {
        ((std::clog << std::setw(14) << std::quoted(argv[0]) << ": ") << ... << m) << std::endl;
    };
    debug("Process.exe started");

    asio::signal_set ss(ioc, SIGTERM);
    ss.async_wait([](boost::system::error_code ec, int num) {
        debug("signal ", num, " (", ec.message(), ")");
    });

    ioc.run();
    debug("Process.exe exit");
}

Now it works:

like image 171
sehe Avatar answered Oct 02 '25 06:10

sehe



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!