fixed excessive spawning of child processes / fixed potential zombie processes (#2924)

This commit is contained in:
Oliver Stöneberg 2020-11-29 14:59:09 +01:00 committed by GitHub
parent 7112f69d7b
commit 873aa075b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 33 additions and 16 deletions

View File

@ -182,7 +182,7 @@ unsigned int ThreadExecutor::check()
std::list<ImportProject::FileSettings>::const_iterator iFileSettings = mSettings.project.fileSettings.begin();
for (;;) {
// Start a new child
size_t nchildren = rpipes.size();
size_t nchildren = childFile.size();
if ((iFile != mFiles.end() || iFileSettings != mSettings.project.fileSettings.end()) && nchildren < mSettings.jobs && checkLoadAverage(nchildren)) {
int pipes[2];
if (pipe(pipes) == -1) {
@ -284,7 +284,7 @@ unsigned int ThreadExecutor::check()
++rp;
}
}
} else if (!childFile.empty()) {
int stat = 0;
pid_t child = waitpid(0, &stat, WNOHANG);
if (child > 0) {
@ -295,21 +295,17 @@ unsigned int ThreadExecutor::check()
childFile.erase(c);
}
if (WIFSIGNALED(stat)) {
if (WIFEXITED(stat)) {
const int exitstaus = WEXITSTATUS(stat);
if (exitstaus != 0) {
std::ostringstream oss;
oss << "Child process exited with " << exitstaus;
reportInternalChildErr(childname, oss.str());
}
} else if (WIFSIGNALED(stat)) {
std::ostringstream oss;
oss << "Internal error: Child process crashed with signal " << WTERMSIG(stat);
std::list<ErrorMessage::FileLocation> locations;
locations.emplace_back(childname, 0, 0);
const ErrorMessage errmsg(locations,
emptyString,
Severity::error,
oss.str(),
"cppcheckError",
false);
if (!mSettings.nomsg.isSuppressed(errmsg.toSuppressionsErrorMessage()))
mErrorLogger.reportErr(errmsg);
oss << "Child process crashed with signal " << WTERMSIG(stat);
reportInternalChildErr(childname, oss.str());
}
}
} else {
@ -359,6 +355,21 @@ void ThreadExecutor::bughuntingReport(const std::string &str)
writeToPipe(REPORT_VERIFICATION, str.c_str());
}
void ThreadExecutor::reportInternalChildErr(const std::string &childname, const std::string &msg)
{
std::list<ErrorMessage::FileLocation> locations;
locations.emplace_back(childname, 0, 0);
const ErrorMessage errmsg(locations,
emptyString,
Severity::error,
"Internal error: " + msg,
"cppcheckError",
false);
if (!mSettings.nomsg.isSuppressed(errmsg.toSuppressionsErrorMessage()))
mErrorLogger.reportErr(errmsg);
}
#elif defined(THREADING_MODEL_WIN)
void ThreadExecutor::addFileContent(const std::string &path, const std::string &content)

View File

@ -102,6 +102,12 @@ private:
*/
bool checkLoadAverage(size_t nchildren);
/**
* @brief Reports internal errors related to child processes
* @param msg The error message
*/
void reportInternalChildErr(const std::string &childname, const std::string &msg);
public:
/**
* @return true if support for threads exist.