@@ -122,47 +122,53 @@ ProcessStarter::Exec(const std::string& executable_path, const std::vector<std::
122122 Promise<ChildProcess> promise;
123123 auto future = promise.get_future ();
124124
125+ LOG_DEBUG () << fmt::format (
126+ " do fork() + {}(), executable_path={}, args=[\' {}\' ], env=[{}]" ,
127+ options.use_path ? " execv" : " execvp" ,
128+ executable_path,
129+ fmt::join (args, " ' '" ),
130+ fmt::join (
131+ env | boost::adaptors::transformed ([](const auto & key_value) {
132+ return key_value.first + ' =' + key_value.second ;
133+ }),
134+ " , "
135+ )
136+ );
125137 thread_control_.RunInEvLoopAsync ([&, promise = std::move (promise)]() mutable {
126- const auto keys = env | boost::adaptors::transformed ([](const auto & key_value) {
127- return key_value.first + ' =' + key_value.second ;
128- });
129- LOG_DEBUG () << fmt::format (
130- " do fork() + {}(), executable_path={}, args=[\' {}\' ], env=[{}]" ,
131- options.use_path ? " execv" : " execvp" ,
132- executable_path,
133- fmt::join (args, " ' '" ),
134- fmt::join (keys, " , " )
135- );
136-
137- const auto pid = utils::CheckSyscall (fork (), " fork" );
138- if (pid) {
139- // in parent thread
140- span.AddTag (" child-process-pid" , pid);
141- LOG_DEBUG () << " Started child process with pid=" << pid;
142- Promise<ChildProcessStatus> exec_result_promise;
143- auto res = ChildProcessMapSet (pid, ev::ChildProcessMapValue (std::move (exec_result_promise)));
144- if (res.second ) {
145- promise.set_value (ChildProcess{ChildProcessImpl{pid, res.first ->status_promise .get_future ()}});
138+ try {
139+ const auto pid = utils::CheckSyscall (fork (), " fork" );
140+ if (pid) {
141+ // in parent thread
142+ span.AddTag (" child-process-pid" , pid);
143+ LOG_DEBUG () << " Started child process with pid=" << pid;
144+ Promise<ChildProcessStatus> exec_result_promise;
145+ auto res = ChildProcessMapSet (pid, ev::ChildProcessMapValue (std::move (exec_result_promise)));
146+ if (res.second ) {
147+ promise.set_value (ChildProcess{ChildProcessImpl{pid, res.first ->status_promise .get_future ()}});
148+ } else {
149+ const auto msg = fmt::format (" process with pid={} already exists in child_process_map" , pid);
150+ LOG_ERROR () << msg << " , send SIGKILL" ;
151+ ChildProcessImpl (pid, Future<ChildProcessStatus>{}).SendSignal (SIGKILL);
152+ promise.set_exception (std::make_exception_ptr (std::runtime_error (msg)));
153+ }
146154 } else {
147- const auto msg = fmt::format (" process with pid={} already exists in child_process_map" , pid);
148- LOG_ERROR () << msg << " , send SIGKILL" ;
149- ChildProcessImpl (pid, Future<ChildProcessStatus>{}).SendSignal (SIGKILL);
150- promise.set_exception (std::make_exception_ptr (std::runtime_error (msg)));
151- }
152- } else {
153- // in child thread
154- try {
155+ // in child thread
155156 try {
156- DoExec (executable_path, args, env, options.stdout_file , options.stderr_file , options.use_path );
157- } catch (const std::exception& ex) {
158- std::cerr << " Cannot execute child: " << ex.what ();
157+ try {
158+ DoExec (executable_path, args, env, options.stdout_file , options.stderr_file , options.use_path );
159+ } catch (const std::exception& ex) {
160+ std::cerr << " Cannot execute child: " << ex.what ();
161+ }
162+ } catch (...) {
163+ // must not do anything in a child
164+ std::abort ();
159165 }
160- } catch (...) {
161- // must not do anything in a child
166+ // on success execve or execvp does not return
162167 std::abort ();
163168 }
164- // on success execve or execvp does not return
165- std::abort ();
169+ } catch (const std::exception& /* e*/ ) {
170+ // utils::CheckSyscall may throw and without the following line a useless "Broken promise" is reported
171+ promise.set_exception (std::current_exception ());
166172 }
167173 });
168174
0 commit comments