fixed excessive spawning of child processes / fixed potential zombie processes (#2924)
This commit is contained in:
parent
7112f69d7b
commit
873aa075b4
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue