Skip to content

Commit 5e76404

Browse files
committed
fixed #12465 - added command-line option --executor to specify the used executor implementation
1 parent 3e84506 commit 5e76404

12 files changed

+211
-21
lines changed

.github/workflows/tsan.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ jobs:
6767
6868
- name: CMake
6969
run: |
70-
cmake -S . -B cmake.output -DCMAKE_BUILD_TYPE=RelWithDebInfo -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=Off -DWITH_QCHART=Off -DUSE_MATCHCOMPILER=Verify -DANALYZE_THREAD=On -DUSE_THREADS=On -DENABLE_CHECK_INTERNAL=On -DUSE_BOOST=On -DCPPCHK_GLIBCXX_DEBUG=Off -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=Off -DDISABLE_DMAKE=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
70+
cmake -S . -B cmake.output -DCMAKE_BUILD_TYPE=RelWithDebInfo -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=Off -DWITH_QCHART=Off -DUSE_MATCHCOMPILER=Verify -DANALYZE_THREAD=On -DENABLE_CHECK_INTERNAL=On -DUSE_BOOST=On -DCPPCHK_GLIBCXX_DEBUG=Off -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=Off -DDISABLE_DMAKE=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
7171
env:
7272
CC: clang-18
7373
CXX: clang++-18
@@ -98,6 +98,8 @@ jobs:
9898
pwd=$(pwd)
9999
cd test/cli
100100
TEST_CPPCHECK_EXE_LOOKUP_PATH="$pwd/cmake.output" python3 -m pytest -Werror --strict-markers -vv
101+
env:
102+
TEST_CPPCHECK_INJECT_EXECUTOR: thread
101103

102104
- name: Run test/cli (-j2)
103105
run: |
@@ -120,6 +122,7 @@ jobs:
120122
if: false
121123
run: |
122124
selfcheck_options="-q -j$(nproc) --std=c++11 --template=selfcheck --showtime=top5_summary -D__GNUC__ --error-exitcode=0 --inline-suppr --suppressions-list=.selfcheck_suppressions --library=gnu --inconclusive --enable=style,performance,portability,warning,missingInclude,internal --exception-handling --debug-warnings --check-level=exhaustive"
125+
selfcheck_options="$selfcheck_options --executor=thread"
123126
cppcheck_options="-D__CPPCHECK__ -DCHECK_INTERNAL -DHAVE_RULES --library=cppcheck-lib -Ilib -Iexternals/simplecpp/ -Iexternals/tinyxml2"
124127
ec=0
125128
./cmake.output/bin/cppcheck $selfcheck_options externals/simplecpp || ec=1

cli/cmdlineparser.cpp

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,7 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a
374374

375375
ImportProject project;
376376

377+
bool executorAuto = true;
377378
int8_t logMissingInclude{0};
378379

379380
for (int i = 1; i < argc; i++) {
@@ -614,6 +615,36 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a
614615
#endif
615616
}
616617

618+
else if (std::strncmp(argv[i], "--executor=", 11) == 0) {
619+
const std::string type = 11 + argv[i];
620+
if (type == "auto") {
621+
executorAuto = true;
622+
mSettings.executor = Settings::defaultExecutor();
623+
}
624+
else if (type == "thread") {
625+
#if defined(HAS_THREADING_MODEL_THREAD)
626+
executorAuto = false;
627+
mSettings.executor = Settings::ExecutorType::Thread;
628+
#else
629+
mLogger.printError("executor type 'thread' cannot be used as Cppcheck has not been built with a respective threading model.");
630+
return Result::Fail;
631+
#endif
632+
}
633+
else if (type == "process") {
634+
#if defined(HAS_THREADING_MODEL_FORK)
635+
executorAuto = false;
636+
mSettings.executor = Settings::ExecutorType::Process;
637+
#else
638+
mLogger.printError("executor type 'process' cannot be used as Cppcheck has not been built with a respective threading model.");
639+
return Result::Fail;
640+
#endif
641+
}
642+
else {
643+
mLogger.printError("unknown executor: '" + type + "'.");
644+
return Result::Fail;
645+
}
646+
}
647+
617648
// Filter errors
618649
else if (std::strncmp(argv[i], "--exitcode-suppressions=", 24) == 0) {
619650
// exitcode-suppressions=filename.txt
@@ -751,7 +782,7 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a
751782
}
752783

753784
else if (std::strncmp(argv[i], "-l", 2) == 0) {
754-
#ifdef THREADING_MODEL_FORK
785+
#ifdef HAS_THREADING_MODEL_FORK
755786
std::string numberString;
756787

757788
// "-l 3"
@@ -1276,6 +1307,10 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a
12761307
if (!loadCppcheckCfg())
12771308
return Result::Fail;
12781309

1310+
// TODO: bail out?
1311+
if (!executorAuto && mSettings.useSingleJob())
1312+
mLogger.printMessage("'--executor' has no effect as only a single job will be used.");
1313+
12791314
// Default template format..
12801315
if (mSettings.templateFormat.empty()) {
12811316
mSettings.templateFormat = "{bold}{file}:{line}:{column}: {red}{inconclusive:{magenta}}{severity}:{inconclusive: inconclusive:}{default} {message} [{id}]{reset}\\n{code}";
@@ -1432,6 +1467,8 @@ void CmdLineParser::printHelp() const
14321467
" provided. Note that your operating system can modify\n"
14331468
" this value, e.g. '256' can become '0'.\n"
14341469
" --errorlist Print a list of all the error messages in XML format.\n"
1470+
" --executor=<type>\n"
1471+
" Specifies the executor to use. Possible values: auto, thread, processor.\n"
14351472
" --exitcode-suppressions=<file>\n"
14361473
" Used when certain messages should be displayed but\n"
14371474
" should not cause a non-zero exitcode.\n"

cli/cppcheckexecutor.cpp

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,10 @@
3333
#include "suppressions.h"
3434
#include "utils.h"
3535

36-
#if defined(THREADING_MODEL_THREAD)
36+
#if defined(HAS_THREADING_MODEL_THREAD)
3737
#include "threadexecutor.h"
38-
#elif defined(THREADING_MODEL_FORK)
38+
#endif
39+
#if defined(HAS_THREADING_MODEL_FORK)
3940
#include "processexecutor.h"
4041
#endif
4142

@@ -271,18 +272,24 @@ int CppCheckExecutor::check_internal(const Settings& settings) const
271272
cppcheck.settings() = settings; // this is a copy
272273
auto& suppressions = cppcheck.settings().supprs.nomsg;
273274

274-
unsigned int returnValue;
275+
unsigned int returnValue = 0;
275276
if (settings.useSingleJob()) {
276277
// Single process
277278
SingleExecutor executor(cppcheck, mFiles, mFileSettings, settings, suppressions, stdLogger);
278279
returnValue = executor.check();
279280
} else {
280-
#if defined(THREADING_MODEL_THREAD)
281-
ThreadExecutor executor(mFiles, mFileSettings, settings, suppressions, stdLogger, CppCheckExecutor::executeCommand);
282-
#elif defined(THREADING_MODEL_FORK)
283-
ProcessExecutor executor(mFiles, mFileSettings, settings, suppressions, stdLogger, CppCheckExecutor::executeCommand);
281+
#if defined(HAS_THREADING_MODEL_THREAD)
282+
if (settings.executor == Settings::ExecutorType::Thread) {
283+
ThreadExecutor executor(mFiles, mFileSettings, settings, suppressions, stdLogger, CppCheckExecutor::executeCommand);
284+
returnValue = executor.check();
285+
}
286+
#endif
287+
#if defined(HAS_THREADING_MODEL_FORK)
288+
if (settings.executor == Settings::ExecutorType::Process) {
289+
ProcessExecutor executor(mFiles, mFileSettings, settings, suppressions, stdLogger, CppCheckExecutor::executeCommand);
290+
returnValue = executor.check();
291+
}
284292
#endif
285-
returnValue = executor.check();
286293
}
287294

288295
cppcheck.analyseWholeProgram(settings.buildDir, mFiles, mFileSettings);

cmake/compilerDefinitions.cmake

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ if (ENABLE_CHECK_INTERNAL)
4141
add_definitions(-DCHECK_INTERNAL)
4242
endif()
4343

44-
if (USE_THREADS)
45-
add_definitions(-DUSE_THREADS)
44+
if (DISALLOW_THREAD_EXECUTOR)
45+
add_definitions(-DDISALLOW_THREAD_EXECUTOR)
4646
endif()
4747

4848
if (MSVC AND DISABLE_CRTDBG_MAP_ALLOC)

cmake/options.cmake

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,14 @@ if (BUILD_CORE_DLL)
5858
set(USE_BUNDLED_TINYXML2 ON)
5959
endif()
6060
option(CPPCHK_GLIBCXX_DEBUG "Usage of STL debug checks in Debug build" ON)
61-
option(USE_THREADS "Usage of threads instead of fork() for -j" OFF)
61+
option(DISALLOW_THREAD_EXECUTOR "Disallow usage of ThreadExecutor for -j" OFF)
6262
option(USE_BOOST "Usage of Boost" OFF)
6363
option(USE_LIBCXX "Use libc++ instead of libstdc++" OFF)
6464

65+
if (DISALLOW_THREAD_EXECUTOR AND WIN32)
66+
message(FATAL_ERROR "Cannot disable usage of ThreadExecutor on Windows as no other executor implementation is currently available")
67+
endif()
68+
6569
option(DISABLE_CRTDBG_MAP_ALLOC "Disable usage of Visual Studio C++ memory leak detection in Debug build" OFF)
6670
option(NO_UNIX_SIGNAL_HANDLING "Disable usage of Unix Signal Handling" OFF)
6771
option(NO_UNIX_BACKTRACE_SUPPORT "Disable usage of Unix Backtrace support" OFF)

cmake/printInfo.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ if (HAVE_RULES)
7171
message( STATUS "PCRE_LIBRARY = ${PCRE_LIBRARY}" )
7272
endif()
7373
message( STATUS )
74-
message( STATUS "USE_THREADS = ${USE_THREADS}" )
74+
message( STATUS "DISALLOW_THREAD_EXECUTOR = ${DISALLOW_THREAD_EXECUTOR}" )
7575
message( STATUS "CMAKE_THREAD_LIBS_INIT = ${CMAKE_THREAD_LIBS_INIT}" )
7676
message( STATUS )
7777
message( STATUS "USE_BUNDLED_TINYXML2 = ${USE_BUNDLED_TINYXML2}" )

lib/config.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -151,13 +151,13 @@ static const std::string emptyString;
151151
#endif
152152

153153
#if defined(_WIN32)
154-
#define THREADING_MODEL_THREAD
154+
#define HAS_THREADING_MODEL_THREAD
155155
#define STDCALL __stdcall
156-
#elif defined(USE_THREADS)
157-
#define THREADING_MODEL_THREAD
158-
#define STDCALL
159156
#elif ((defined(__GNUC__) || defined(__sun)) && !defined(__MINGW32__)) || defined(__CPPCHECK__)
160-
#define THREADING_MODEL_FORK
157+
#define HAS_THREADING_MODEL_FORK
158+
#if !defined(DISALLOW_THREAD_EXECUTOR)
159+
#define HAS_THREADING_MODEL_THREAD
160+
#endif
161161
#define STDCALL
162162
#else
163163
#error "No threading model defined"

lib/settings.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
* along with this program. If not, see <http://www.gnu.org/licenses/>.
1717
*/
1818

19+
#include "config.h"
1920
#include "settings.h"
2021
#include "path.h"
2122
#include "summaries.h"
@@ -38,9 +39,11 @@ const char Settings::SafeChecks::XmlExternalVariables[] = "external-variables";
3839

3940
Settings::Settings()
4041
{
42+
// TODO: set default executor
4143
severity.setEnabled(Severity::error, true);
4244
certainty.setEnabled(Certainty::normal, true);
4345
setCheckLevelNormal();
46+
executor = defaultExecutor();
4447
}
4548

4649
std::string Settings::loadCppcheckCfg(Settings& settings, Suppressions& suppressions)
@@ -593,3 +596,14 @@ std::string Settings::getMisraRuleText(const std::string& id, const std::string&
593596
const auto it = mMisraRuleTexts.find(id.substr(id.rfind('-') + 1));
594597
return it != mMisraRuleTexts.end() ? it->second : text;
595598
}
599+
600+
Settings::ExecutorType Settings::defaultExecutor()
601+
{
602+
static constexpr ExecutorType defaultExecutor =
603+
#if defined(HAS_THREADING_MODEL_FORK)
604+
ExecutorType::Process;
605+
#elif defined(HAS_THREADING_MODEL_THREAD)
606+
ExecutorType::Thread;
607+
#endif
608+
return defaultExecutor;
609+
}

lib/settings.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,18 @@ class CPPCHECKLIB WARN_UNUSED Settings {
195195
bool exceptionHandling{};
196196
#endif
197197

198+
enum class ExecutorType
199+
{
200+
#ifdef HAS_THREADING_MODEL_THREAD
201+
Thread,
202+
#endif
203+
#ifdef HAS_THREADING_MODEL_FORK
204+
Process
205+
#endif
206+
};
207+
208+
ExecutorType executor;
209+
198210
// argv[0]
199211
std::string exename;
200212

@@ -465,6 +477,8 @@ class CPPCHECKLIB WARN_UNUSED Settings {
465477
void setMisraRuleTexts(const std::string& data);
466478
std::string getMisraRuleText(const std::string& id, const std::string& text) const;
467479

480+
static ExecutorType defaultExecutor();
481+
468482
private:
469483
static std::string parseEnabled(const std::string &str, std::tuple<SimpleEnableGroup<Severity>, SimpleEnableGroup<Checks>> &groups);
470484
std::string applyEnabled(const std::string &str, bool enable);

man/cppcheck.1.xml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,9 @@ man(1), man(7), http://www.tldp.org/HOWTO/Man-Page/
117117
<arg choice="opt">
118118
<option>--errorlist</option>
119119
</arg>
120+
<arg choice="opt">
121+
<option>--executor=&lt;type&gt;</option>
122+
</arg>
120123
<arg choice="opt">
121124
<option>--exitcode-suppressions=&lt;file&gt;</option>
122125
</arg>
@@ -328,6 +331,15 @@ Example: '-UDEBUG'</para>
328331
<para>Print a list of all possible error messages in XML format.</para>
329332
</listitem>
330333
</varlistentry>
334+
<varlistentry>
335+
<term>
336+
<option>--executor=&lt;type&gt;</option>
337+
</term>
338+
<listitem>
339+
<para>Specifies the executor to use. Possible values:</para>
340+
<glosslist><glossentry><glossterm>auto</glossterm><glossdef><para>Automatically select (default)</para></glossdef></glossentry><glossentry><glossterm>thread</glossterm><glossdef><para>Perform analysis within a thread in the main process</para></glossdef></glossentry><glossentry><glossterm>proicess</glossterm><glossdef><para>Perform analysis of each file in a separate child process</para></glossdef></glossentry></glosslist>
341+
</listitem>
342+
</varlistentry>
331343
<varlistentry>
332344
<term>
333345
<option>--exitcode-suppressions=&lt;file&gt;</option>

releasenotes.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,6 @@ Other:
2323
- Added '--template=simple'. It is expands to '{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]' without any additional location details.
2424
- Removed deprecated platform type 'Unspecified'. Please use 'unspecified' instead.
2525
- Removed deprecated 'Makefile' option 'SRCDIR'.
26+
- Added CMake option 'DISALLOW_THREAD_EXECUTOR' to control the inclusion of the executor which performs the analysis within a thread of the main process.
27+
- Removed CMake option 'USE_THREADS' in favor of 'DISALLOW_THREAD_EXECUTOR'.
28+
- Added command-line option `--executor=` to specify the executor. Available options are 'auto', 'process' and 'thread'. 'auto' will prefer 'process' if it is available. Note: Windows has no implementation of 'process' as of now so it will always chose 'thread' for now.

0 commit comments

Comments
 (0)