Skip to content

fixed #12465 - added (undocumented) command-line option --executor to specify the used executor implementation #6043

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .github/workflows/tsan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ jobs:

- name: CMake
run: |
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
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
env:
CC: clang-18
CXX: clang++-18
Expand Down Expand Up @@ -98,6 +98,8 @@ jobs:
pwd=$(pwd)
cd test/cli
TEST_CPPCHECK_EXE_LOOKUP_PATH="$pwd/cmake.output" python3 -m pytest -Werror --strict-markers -vv
env:
TEST_CPPCHECK_INJECT_EXECUTOR: thread

- name: Run test/cli (-j2)
run: |
Expand Down Expand Up @@ -129,6 +131,7 @@ jobs:
if: false
run: |
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"
selfcheck_options="$selfcheck_options --executor=thread"
cppcheck_options="-D__CPPCHECK__ -DCHECK_INTERNAL -DHAVE_RULES --library=cppcheck-lib -Ilib -Iexternals/simplecpp/ -Iexternals/tinyxml2"
ec=0
./cmake.output/bin/cppcheck $selfcheck_options externals/simplecpp || ec=1
Expand Down
37 changes: 36 additions & 1 deletion cli/cmdlineparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,7 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a

ImportProject project;

bool executorAuto = true;
int8_t logMissingInclude{0};

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

else if (std::strncmp(argv[i], "--executor=", 11) == 0) {
const std::string type = 11 + argv[i];
if (type == "auto") {
executorAuto = true;
mSettings.executor = Settings::defaultExecutor();
}
else if (type == "thread") {
#if defined(HAS_THREADING_MODEL_THREAD)
executorAuto = false;
mSettings.executor = Settings::ExecutorType::Thread;
#else
mLogger.printError("executor type 'thread' cannot be used as Cppcheck has not been built with a respective threading model.");
return Result::Fail;
#endif
}
else if (type == "process") {
#if defined(HAS_THREADING_MODEL_FORK)
executorAuto = false;
mSettings.executor = Settings::ExecutorType::Process;
#else
mLogger.printError("executor type 'process' cannot be used as Cppcheck has not been built with a respective threading model.");
return Result::Fail;
#endif
}
else {
mLogger.printError("unknown executor: '" + type + "'.");
return Result::Fail;
}
}

// Filter errors
else if (std::strncmp(argv[i], "--exitcode-suppressions=", 24) == 0) {
// exitcode-suppressions=filename.txt
Expand Down Expand Up @@ -751,7 +782,7 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a
}

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

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

// TODO: bail out?
if (!executorAuto && mSettings.useSingleJob())
mLogger.printMessage("'--executor' has no effect as only a single job will be used.");

// Default template format..
if (mSettings.templateFormat.empty()) {
mSettings.templateFormat = "{bold}{file}:{line}:{column}: {red}{inconclusive:{magenta}}{severity}:{inconclusive: inconclusive:}{default} {message} [{id}]{reset}\\n{code}";
Expand Down
23 changes: 15 additions & 8 deletions cli/cppcheckexecutor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,10 @@
#include "suppressions.h"
#include "utils.h"

#if defined(THREADING_MODEL_THREAD)
#if defined(HAS_THREADING_MODEL_THREAD)
#include "threadexecutor.h"
#elif defined(THREADING_MODEL_FORK)
#endif
#if defined(HAS_THREADING_MODEL_FORK)
#include "processexecutor.h"
#endif

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

unsigned int returnValue;
unsigned int returnValue = 0;
if (settings.useSingleJob()) {
// Single process
SingleExecutor executor(cppcheck, mFiles, mFileSettings, settings, suppressions, stdLogger);
returnValue = executor.check();
} else {
#if defined(THREADING_MODEL_THREAD)
ThreadExecutor executor(mFiles, mFileSettings, settings, suppressions, stdLogger, CppCheckExecutor::executeCommand);
#elif defined(THREADING_MODEL_FORK)
ProcessExecutor executor(mFiles, mFileSettings, settings, suppressions, stdLogger, CppCheckExecutor::executeCommand);
#if defined(HAS_THREADING_MODEL_THREAD)
if (settings.executor == Settings::ExecutorType::Thread) {
ThreadExecutor executor(mFiles, mFileSettings, settings, suppressions, stdLogger, CppCheckExecutor::executeCommand);
returnValue = executor.check();
}
#endif
#if defined(HAS_THREADING_MODEL_FORK)
if (settings.executor == Settings::ExecutorType::Process) {
ProcessExecutor executor(mFiles, mFileSettings, settings, suppressions, stdLogger, CppCheckExecutor::executeCommand);
returnValue = executor.check();
}
#endif
returnValue = executor.check();
}

cppcheck.analyseWholeProgram(settings.buildDir, mFiles, mFileSettings);
Expand Down
4 changes: 2 additions & 2 deletions cmake/compilerDefinitions.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ if (ENABLE_CHECK_INTERNAL)
add_definitions(-DCHECK_INTERNAL)
endif()

if (USE_THREADS)
add_definitions(-DUSE_THREADS)
if (DISALLOW_THREAD_EXECUTOR)
add_definitions(-DDISALLOW_THREAD_EXECUTOR)
endif()

if (MSVC AND DISABLE_CRTDBG_MAP_ALLOC)
Expand Down
6 changes: 5 additions & 1 deletion cmake/options.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,14 @@ if (BUILD_CORE_DLL)
set(USE_BUNDLED_TINYXML2 ON)
endif()
option(CPPCHK_GLIBCXX_DEBUG "Usage of STL debug checks in Debug build" ON)
option(USE_THREADS "Usage of threads instead of fork() for -j" OFF)
option(DISALLOW_THREAD_EXECUTOR "Disallow usage of ThreadExecutor for -j" OFF)
option(USE_BOOST "Usage of Boost" OFF)
option(USE_LIBCXX "Use libc++ instead of libstdc++" OFF)

if (DISALLOW_THREAD_EXECUTOR AND WIN32)
message(FATAL_ERROR "Cannot disable usage of ThreadExecutor on Windows as no other executor implementation is currently available")
endif()

option(DISABLE_CRTDBG_MAP_ALLOC "Disable usage of Visual Studio C++ memory leak detection in Debug build" OFF)
option(NO_UNIX_SIGNAL_HANDLING "Disable usage of Unix Signal Handling" OFF)
option(NO_UNIX_BACKTRACE_SUPPORT "Disable usage of Unix Backtrace support" OFF)
Expand Down
2 changes: 1 addition & 1 deletion cmake/printInfo.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ if (HAVE_RULES)
message( STATUS "PCRE_LIBRARY = ${PCRE_LIBRARY}" )
endif()
message( STATUS )
message( STATUS "USE_THREADS = ${USE_THREADS}" )
message( STATUS "DISALLOW_THREAD_EXECUTOR = ${DISALLOW_THREAD_EXECUTOR}" )
message( STATUS "CMAKE_THREAD_LIBS_INIT = ${CMAKE_THREAD_LIBS_INIT}" )
message( STATUS )
message( STATUS "USE_BUNDLED_TINYXML2 = ${USE_BUNDLED_TINYXML2}" )
Expand Down
10 changes: 5 additions & 5 deletions lib/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,13 +151,13 @@ static const std::string emptyString;
#endif

#if defined(_WIN32)
#define THREADING_MODEL_THREAD
#define HAS_THREADING_MODEL_THREAD
#define STDCALL __stdcall
#elif defined(USE_THREADS)
#define THREADING_MODEL_THREAD
#define STDCALL
#elif ((defined(__GNUC__) || defined(__sun)) && !defined(__MINGW32__)) || defined(__CPPCHECK__)
#define THREADING_MODEL_FORK
#define HAS_THREADING_MODEL_FORK
#if !defined(DISALLOW_THREAD_EXECUTOR)
#define HAS_THREADING_MODEL_THREAD
#endif
#define STDCALL
#else
#error "No threading model defined"
Expand Down
13 changes: 13 additions & 0 deletions lib/settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include "config.h"
#include "settings.h"
#include "path.h"
#include "summaries.h"
Expand All @@ -41,6 +42,7 @@ Settings::Settings()
severity.setEnabled(Severity::error, true);
certainty.setEnabled(Certainty::normal, true);
setCheckLevelNormal();
executor = defaultExecutor();
}

std::string Settings::loadCppcheckCfg(Settings& settings, Suppressions& suppressions)
Expand Down Expand Up @@ -593,3 +595,14 @@ std::string Settings::getMisraRuleText(const std::string& id, const std::string&
const auto it = mMisraRuleTexts.find(id.substr(id.rfind('-') + 1));
return it != mMisraRuleTexts.end() ? it->second : text;
}

Settings::ExecutorType Settings::defaultExecutor()
{
static constexpr ExecutorType defaultExecutor =
#if defined(HAS_THREADING_MODEL_FORK)
ExecutorType::Process;
#elif defined(HAS_THREADING_MODEL_THREAD)
ExecutorType::Thread;
#endif
return defaultExecutor;
}
14 changes: 14 additions & 0 deletions lib/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,18 @@ class CPPCHECKLIB WARN_UNUSED Settings {
bool exceptionHandling{};
#endif

enum class ExecutorType
{
#ifdef HAS_THREADING_MODEL_THREAD
Thread,
#endif
#ifdef HAS_THREADING_MODEL_FORK
Process
#endif
};

ExecutorType executor;

// argv[0]
std::string exename;

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

static ExecutorType defaultExecutor();

private:
static std::string parseEnabled(const std::string &str, std::tuple<SimpleEnableGroup<Severity>, SimpleEnableGroup<Checks>> &groups);
std::string applyEnabled(const std::string &str, bool enable);
Expand Down
2 changes: 2 additions & 0 deletions releasenotes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,5 @@ Other:
- Added '--template=simple'. It is expands to '{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]' without any additional location details.
- Removed deprecated platform type 'Unspecified'. Please use 'unspecified' instead.
- Removed deprecated 'Makefile' option 'SRCDIR'.
- Added CMake option 'DISALLOW_THREAD_EXECUTOR' to control the inclusion of the executor which performs the analysis within a thread of the main process.
- Removed CMake option 'USE_THREADS' in favor of 'DISALLOW_THREAD_EXECUTOR'.
15 changes: 15 additions & 0 deletions test/cli/testutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,21 @@ def cppcheck(args, env=None, remove_checkers_report=True, cwd=None, cppcheck_exe
arg_clang = '--clang=' + str(os.environ['TEST_CPPCHECK_INJECT_CLANG'])
args.append(arg_clang)

if 'TEST_CPPCHECK_INJECT_EXECUTOR' in os.environ:
found_jn = False
found_executor = False
for arg in args:
if arg.startswith('-j') and arg != '-j1':
found_jn = True
continue
if arg.startswith('--executor'):
found_executor = True
continue
# only add '--executor' if we are actually using multiple jobs
if found_jn and not found_executor:
arg_executor = '--executor=' + str(os.environ['TEST_CPPCHECK_INJECT_EXECUTOR'])
args.append(arg_executor)

logging.info(exe + ' ' + ' '.join(args))
p = subprocess.Popen([exe] + args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env, cwd=cwd)
try:
Expand Down
Loading