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

View File

@ -102,6 +102,12 @@ private:
*/ */
bool checkLoadAverage(size_t nchildren); 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: public:
/** /**
* @return true if support for threads exist. * @return true if support for threads exist.