Skip to content

Commit 9bfc2b6

Browse files
committed
Fixed crashes random crashes in multithreading caused by useless creation of CheckUnusedFunctions instance per thread.
1 parent 73fc3d6 commit 9bfc2b6

5 files changed

Lines changed: 22 additions & 7 deletions

File tree

lib/checkunusedfunctions.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@
2727

2828

2929

30+
// Register this check class
31+
CheckUnusedFunctions CheckUnusedFunctions::instance;
32+
3033

3134
//---------------------------------------------------------------------------
3235
// FUNCTION USAGE - Check for unused functions etc

lib/checkunusedfunctions.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
/** @brief Check for functions never called */
3232
/// @{
3333

34-
class CPPCHECKLIB CheckUnusedFunctions: public Check {
34+
class CPPCHECKLIB CheckUnusedFunctions : public Check {
3535
public:
3636
/** @brief This constructor is used when registering the CheckUnusedFunctions */
3737
CheckUnusedFunctions() : Check(myName()) {
@@ -49,6 +49,8 @@ class CPPCHECKLIB CheckUnusedFunctions: public Check {
4949

5050
void check(ErrorLogger * const errorLogger);
5151

52+
static CheckUnusedFunctions instance;
53+
5254
private:
5355

5456
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const {

lib/cppcheck.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ void CppCheck::checkFunctionUsage()
282282
if (_settings._errorsOnly == false)
283283
_errorLogger.reportOut("Checking usage of global functions..");
284284

285-
_checkUnusedFunctions.check(this);
285+
CheckUnusedFunctions::instance.check(this);
286286

287287
_settings._verbose = verbose_orig;
288288
}
@@ -359,7 +359,7 @@ void CppCheck::checkFile(const std::string &code, const char FileName[])
359359
}
360360

361361
// call all "runChecks" in all registered Check classes
362-
for (std::list<Check *>::iterator it = Check::instances().begin(); it != Check::instances().end(); ++it) {
362+
for (std::list<Check *>::const_iterator it = Check::instances().begin(); it != Check::instances().end(); ++it) {
363363
if (_settings.terminated())
364364
return;
365365

@@ -368,7 +368,7 @@ void CppCheck::checkFile(const std::string &code, const char FileName[])
368368
}
369369

370370
if (_settings.isEnabled("unusedFunction") && _settings._jobs == 1)
371-
_checkUnusedFunctions.parseTokens(_tokenizer, FileName, &_settings);
371+
CheckUnusedFunctions::instance.parseTokens(_tokenizer, FileName, &_settings);
372372

373373
executeRules("normal", _tokenizer);
374374

@@ -382,7 +382,7 @@ void CppCheck::checkFile(const std::string &code, const char FileName[])
382382
return;
383383

384384
// call all "runSimplifiedChecks" in all registered Check classes
385-
for (std::list<Check *>::iterator it = Check::instances().begin(); it != Check::instances().end(); ++it) {
385+
for (std::list<Check *>::const_iterator it = Check::instances().begin(); it != Check::instances().end(); ++it) {
386386
if (_settings.terminated())
387387
return;
388388

@@ -638,7 +638,7 @@ void CppCheck::getErrorMessages()
638638
tooManyConfigsError("",0U);
639639

640640
// call all "getErrorMessages" in all registered Check classes
641-
for (std::list<Check *>::iterator it = Check::instances().begin(); it != Check::instances().end(); ++it)
641+
for (std::list<Check *>::const_iterator it = Check::instances().begin(); it != Check::instances().end(); ++it)
642642
(*it)->getErrorMessages(this, &_settings);
643643

644644
Tokenizer::getErrorMessages(this, &_settings);

lib/cppcheck.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,6 @@ class CPPCHECKLIB CppCheck : ErrorLogger {
194194
*/
195195
virtual void reportInfo(const ErrorLogger::ErrorMessage &msg);
196196

197-
CheckUnusedFunctions _checkUnusedFunctions;
198197
ErrorLogger &_errorLogger;
199198

200199
/** @brief Current preprocessor configuration */

test/testthreadexecutor.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ class TestThreadExecutor : public TestFixture {
6565

6666
void run() {
6767
TEST_CASE(deadlock_with_many_errors);
68+
TEST_CASE(many_threads);
6869
TEST_CASE(no_errors_more_files);
6970
TEST_CASE(no_errors_less_files);
7071
TEST_CASE(no_errors_equal_amount_files);
@@ -84,6 +85,16 @@ class TestThreadExecutor : public TestFixture {
8485
check(2, 3, 3, oss.str());
8586
}
8687

88+
void many_threads() {
89+
std::ostringstream oss;
90+
oss << "int main()\n"
91+
<< "{\n";
92+
oss << " char *a = malloc(10);\n";
93+
oss << " return 0;\n"
94+
<< "}";
95+
check(20, 100, 100, oss.str());
96+
}
97+
8798
void no_errors_more_files() {
8899
std::ostringstream oss;
89100
oss << "int main()\n"

0 commit comments

Comments
 (0)