8d079855b5e9b2d01e1ac8f851536ce300e97360 galt Wed Jun 26 20:47:32 2019 -0700 Trying to gather more information about how the child exits. Wait was returning while the child mysql process was still running. These changes will make it more explicit. diff --git src/hg/lib/sqlProg.c src/hg/lib/sqlProg.c index dbcda73..25b11e3 100644 --- src/hg/lib/sqlProg.c +++ src/hg/lib/sqlProg.c @@ -185,32 +185,32 @@ safef(homePath, sizeof homePath, "%s/%s", homeDir, file->name); remove(homePath); } } slFreeList(&fileList); } void sqlExecProgProfile(char *profile, char *prog, char **progArgs, int userArgc, char *userArgv[]) /* * Exec one of the sql programs using user and password defined in localDb.XXX variables from ~/.hg.conf * progArgs is NULL-terminate array of program-specific arguments to add, * which maybe NULL. userArgv are arguments passed in from the command line. * The program is execvp-ed, this function does not return. */ { -int i, j = 0, nargc=cntArgv(progArgs)+userArgc+6, returnStatus; -pid_t child_id; +int i, j = 0, nargc=cntArgv(progArgs)+userArgc+6, status; +pid_t childId; char **nargv, defaultFileName[256], defaultFileArg[256], *homeDir; // install cleanup signal handlers sqlProgInitSigHandlers(); /* Assemble defaults file */ if ((homeDir = getenv("HOME")) == NULL) errAbort("sqlExecProgProfile: HOME is not defined in environment; cannot create temporary password file"); nukeOldCnfs(homeDir); // look for special parameter -profile=name for (i = 0; i < userArgc; i++) if (startsWith("-profile=", userArgv[i])) profile=cloneString(userArgv[i]+strlen("-profile=")); @@ -226,40 +226,60 @@ nargv[j++] = defaultFileArg; /* --defaults-file must come before other options */ if (progArgs != NULL) { for (i = 0; progArgs[i] != NULL; i++) nargv[j++] = progArgs[i]; } for (i = 0; i < userArgc; i++) if (!startsWith("-profile=", userArgv[i])) nargv[j++] = userArgv[i]; nargv[j++] = NULL; // flush before forking so we can't accidentally get two copies of the output fflush(stdout); fflush(stderr); -child_id = fork(); -killChildPid = child_id; -if (child_id == 0) +childId = fork(); +killChildPid = childId; +if (childId == 0) { execvp(nargv[0], nargv); _exit(42); /* Why 42? Why not? Need something user defined that mysql isn't going to return */ } else { /* Wait until the child process completes, then delete the temp file */ - wait(&returnStatus); - unlink (defaultFileName); - if (WIFEXITED(returnStatus)) + + pid_t endId = waitpid(childId, &status, 0); + if (endId == -1) /* error calling waitpid */ + { + errAbort("waitpid error"); + exit(1); + } + else if (endId == childId) /* child ended */ + { + if (WIFEXITED(status)) { - int childExitStatus = WEXITSTATUS(returnStatus); + // Child ended normally. + unlink (defaultFileName); + int childExitStatus = WEXITSTATUS(status); if (childExitStatus == 42) errAbort("sqlExecProgProfile: exec failed"); else + { // Propagate child's exit status: _exit(childExitStatus); } + } + else if (WIFSIGNALED(status)) + errAbort("Child mysql process ended because of an uncaught signal.n"); + else if (WIFSTOPPED(status)) + errAbort("Child mysql process has stopped.n"); else - errAbort("sqlExecProgProfile: child process exited with abnormal status %d", returnStatus); + errAbort("sqlExecProgProfile: child mysql process exited with abnormal status %d", status); + } + else if (endId == 0) /* child still running should not happen */ + { + errAbort("Unexpected error, child still running"); + } } }