Skip to content

Commit 38af220

Browse files
author
Daniel Kroening
authored
Merge pull request #2918 from diffblue/child_management
only selectively kill child, not entire process group
2 parents 7de9df8 + 1c8fc56 commit 38af220

File tree

3 files changed

+49
-25
lines changed

3 files changed

+49
-25
lines changed

src/util/run.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,17 +342,23 @@ int run(
342342
}
343343
else /* fork() returns new pid to the parent process */
344344
{
345+
// must do before resuming signals to avoid race
346+
register_child(childpid);
347+
345348
// resume signals
346349
sigprocmask(SIG_SETMASK, &old_mask, nullptr);
347350

348351
int status; /* parent process: child's exit status */
349352

350353
/* wait for child to exit, and store its status */
351354
while(waitpid(childpid, &status, 0)==-1)
355+
{
352356
if(errno==EINTR)
353357
continue; // try again
354358
else
355359
{
360+
unregister_child();
361+
356362
perror("Waiting for child process failed");
357363
if(stdin_fd!=STDIN_FILENO)
358364
close(stdin_fd);
@@ -362,6 +368,9 @@ int run(
362368
close(stderr_fd);
363369
return 1;
364370
}
371+
}
372+
373+
unregister_child();
365374

366375
if(stdin_fd!=STDIN_FILENO)
367376
close(stdin_fd);

src/util/signal_catcher.cpp

Lines changed: 34 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -9,72 +9,81 @@ Author: Daniel Kroening, [email protected]
99
\*******************************************************************/
1010

1111
#include "signal_catcher.h"
12+
#include "invariant.h"
1213

1314
#if defined(_WIN32)
14-
#include <process.h>
1515
#else
1616
#include <cstdlib>
17-
#include <csignal>
1817
#endif
1918

20-
#include <vector>
21-
2219
// Here we have an instance of an ugly global object.
2320
// It keeps track of any child processes that we'll kill
24-
// when we are told to terminate.
21+
// when we are told to terminate. "No child" is indicated by '0'.
2522

2623
#ifdef _WIN32
2724
#else
28-
std::vector<pid_t> pids_of_children;
25+
pid_t child_pid = 0;
26+
27+
void register_child(pid_t pid)
28+
{
29+
PRECONDITION(child_pid == 0);
30+
child_pid = pid;
31+
}
32+
33+
void unregister_child()
34+
{
35+
PRECONDITION(child_pid != 0);
36+
child_pid = 0;
37+
}
2938
#endif
3039

3140
void install_signal_catcher()
3241
{
33-
#if defined(_WIN32)
34-
#else
42+
#if defined(_WIN32)
43+
#else
3544
// declare act to deal with action on signal set
3645
// NOLINTNEXTLINE(readability/identifiers)
3746
static struct sigaction act;
3847

39-
act.sa_handler=signal_catcher;
40-
act.sa_flags=0;
48+
act.sa_handler = signal_catcher;
49+
act.sa_flags = 0;
4150
sigfillset(&(act.sa_mask));
4251

4352
// install signal handler
4453
sigaction(SIGTERM, &act, nullptr);
45-
#endif
54+
#endif
4655
}
4756

4857
void remove_signal_catcher()
4958
{
50-
#if defined(_WIN32)
51-
#else
59+
#if defined(_WIN32)
60+
#else
5261
// declare act to deal with action on signal set
5362
// NOLINTNEXTLINE(readability/identifiers)
5463
static struct sigaction act;
5564

56-
act.sa_handler=SIG_DFL;
57-
act.sa_flags=0;
65+
act.sa_handler = SIG_DFL;
66+
act.sa_flags = 0;
5867
sigfillset(&(act.sa_mask));
5968

6069
sigaction(SIGTERM, &act, nullptr);
61-
#endif
70+
#endif
6271
}
6372

6473
void signal_catcher(int sig)
6574
{
66-
#if defined(_WIN32)
67-
#else
75+
#if defined(_WIN32)
76+
#else
6877

69-
#if 1
78+
#if 0
7079
// kill any children by killing group
7180
killpg(0, sig);
72-
#else
73-
// pass on to any children
74-
for(const auto &pid : pids_of_children)
75-
kill(pid, sig);
76-
#endif
81+
#else
82+
// pass on to our child, if any
83+
if(child_pid != 0)
84+
kill(child_pid, sig);
85+
#endif
7786

7887
exit(sig); // should contemplate something from sysexits.h
79-
#endif
88+
#endif
8089
}

src/util/signal_catcher.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,10 @@ void install_signal_catcher();
1414
void remove_signal_catcher();
1515
void signal_catcher(int sig);
1616

17+
#ifndef _WIN32
18+
#include <csignal>
19+
void register_child(pid_t);
20+
void unregister_child();
21+
#endif
22+
1723
#endif // CPROVER_UTIL_SIGNAL_CATCHER_H

0 commit comments

Comments
 (0)