Skip to content

Commit 08ef174

Browse files
committed
Fix signal handling - waiting for multiple processes
In tooldata_db.cc (line 67), the old code does: 1. waitpid(..., WNOHANG) in a while (...) ; loop with an empty body. 2. Then evaluates WIFSIGNALED(status) and WIFEXITED(status) once, after the loop. The problem is: 1. waitpid only writes status when it returns > 0. 2. With WNOHANG, it can return 0 immediately (no state change yet), or -1 on error. 3. In those cases, status is not guaranteed to be written. 4. The code then reads status anyway via WIF* macros, so it can read stale/uninitialized data. 5. That can cause false logs and incorrectly set db_live = 0. What the patch changes: 1. It moves WIFSIGNALED/WIFEXITED checks inside the while (waitpid(...) > 0) loop. 2. status is only inspected in iterations where waitpid definitely produced a valid child status. 3. If no child was reapable, the loop does not run, and nothing is logged or toggled. 4. If multiple children changed state, each valid status is handled, instead of only the last one.
1 parent 8839d22 commit 08ef174

1 file changed

Lines changed: 20 additions & 18 deletions

File tree

src/emc/tooldata/tooldata_db.cc

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -64,29 +64,31 @@ static int pipes[NUM_PIPES][2];
6464
static bool is_random_toolchanger = 0;
6565
static char db_childname[PATH_MAX];
6666

67-
static void handle_sigchild(int s)
67+
static void handle_sigchild(int /*s*/)
6868
{
6969
pid_t pid;
70-
int status;
71-
while((pid = waitpid(-1, &status, WUNTRACED | WCONTINUED | WNOHANG)) > 0) ;
72-
if (WIFSIGNALED(status)) {
73-
db_live = 0;
74-
fprintf(stderr,"%5d !!!%s terminated by signal %d\n"
75-
,getpid(),db_childname,WTERMSIG(status));
76-
}
77-
if (WIFEXITED(status)) {
78-
db_live = 0;
79-
fprintf(stderr,"%5d ===%s normal exit status=%d\n"
70+
int status = 0;
71+
while((pid = waitpid(-1, &status, WUNTRACED | WCONTINUED | WNOHANG)) > 0) {
72+
73+
if (WIFSIGNALED(status)) {
74+
db_live = 0;
75+
fprintf(stderr,"%5d !!!%s terminated by signal %d\n"
76+
,getpid(),db_childname,WTERMSIG(status));
77+
}
78+
if (WIFEXITED(status)) {
79+
db_live = 0;
80+
fprintf(stderr,"%5d ===%s normal exit status=%d\n"
8081
,getpid(),db_childname,WEXITSTATUS(status));
81-
}
82+
}
8283
#if 0
83-
if (WIFSTOPPED(status)) {
84-
fprintf(stderr,"%5d ===%s stopped\n",getpid(),db_childname);
85-
}
86-
if (WIFCONTINUED(status)) {
87-
fprintf(stderr,"%5d ===%s continued\n",getpid(),db_childname);
88-
}
84+
if (WIFSTOPPED(status)) {
85+
fprintf(stderr,"%5d ===%s stopped\n",getpid(),db_childname);
86+
}
87+
if (WIFCONTINUED(status)) {
88+
fprintf(stderr,"%5d ===%s continued\n",getpid(),db_childname);
89+
}
8990
#endif
91+
}
9092
}
9193

9294
static int fork_create(int myargc,char *const myargv[])

0 commit comments

Comments
 (0)