From 05052d7cccf8f69f877746fa0c35484ac2d41b52 Mon Sep 17 00:00:00 2001 From: firewave Date: Tue, 14 Jan 2025 12:35:06 +0100 Subject: [PATCH] added CLI option `--debug-ipc` to log `ProcessExecutor` IPC communication [skip ci] --- cli/cmdlineparser.cpp | 3 +++ cli/processexecutor.cpp | 11 +++++++++-- lib/check.cpp | 1 + lib/settings.h | 3 +++ test/cli/other_test.py | 26 +++++++++++++++++++++++++- test/testcmdlineparser.cpp | 8 ++++++++ 6 files changed, 49 insertions(+), 3 deletions(-) diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index 2069c89579c..865580f049d 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -631,6 +631,9 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a else if (std::strcmp(argv[i], "--debug-ignore") == 0) mSettings.debugignore = true; + else if (std::strcmp(argv[i], "--debug-ipc") == 0) + mSettings.debugipc = true; + // Show --debug output after the first simplifications else if (std::strcmp(argv[i], "--debug") == 0 || std::strcmp(argv[i], "--debug-normal") == 0) diff --git a/cli/processexecutor.cpp b/cli/processexecutor.cpp index cc6c7baf214..18f4a822192 100644 --- a/cli/processexecutor.cpp +++ b/cli/processexecutor.cpp @@ -80,7 +80,7 @@ namespace { public: enum PipeSignal : std::uint8_t {REPORT_OUT='1',REPORT_ERROR='2',REPORT_SUPPR_INLINE='3',REPORT_SUPPR='4',CHILD_END='5',REPORT_METRIC='6',REPORT_TIMER='7'}; - explicit PipeWriter(int pipe) : mWpipe(pipe) {} + explicit PipeWriter(int pipe, bool debug) : mWpipe(pipe), mDebug(debug) {} void reportOut(const std::string &outmsg, Color c) override { writeToPipe(REPORT_OUT, static_cast(c) + outmsg); @@ -153,6 +153,9 @@ namespace { void writeToPipe(PipeSignal type, const std::string &data) const { + if (mDebug) + std::cout << "writeToPipe - " << type << " - " << data << std::endl; + { const auto t = static_cast(type); writeToPipeInternal(type, &t, 1); @@ -169,6 +172,7 @@ namespace { } const int mWpipe; + const bool mDebug; }; } @@ -235,6 +239,9 @@ bool ProcessExecutor::handleRead(int rpipe, unsigned int &result, const std::str } while (bytes_to_read != 0); } + if (mSettings.debugipc) + std::cout << "handleRead - " << type << " - " << buf << std::endl; + bool res = true; if (type == PipeWriter::REPORT_OUT) { // the first character is the color @@ -378,7 +385,7 @@ unsigned int ProcessExecutor::check() mTimerResults->reset(); // TODO: how to "reset" mSuppressions? - PipeWriter pipewriter(pipes[1]); + PipeWriter pipewriter(pipes[1], mSettings.debugipc); CppCheck fileChecker(mSettings, mSuppressions, pipewriter, mTimerResults, false, mExecuteCommand); unsigned int resultOfCheck = 0; diff --git a/lib/check.cpp b/lib/check.cpp index 58b8dbfe0e1..1d0cfe61792 100644 --- a/lib/check.cpp +++ b/lib/check.cpp @@ -130,6 +130,7 @@ ErrorPath Check::getErrorPath(const Token* errtok, const ValueFlow::Value* value void Check::logChecker(const char id[]) { + // TODO: only issue when we would actually use it later on reportError(nullptr, Severity::internal, "logChecker", id); } diff --git a/lib/settings.h b/lib/settings.h index b7b23675aae..8e0881562ed 100644 --- a/lib/settings.h +++ b/lib/settings.h @@ -202,6 +202,9 @@ class CPPCHECKLIB WARN_UNUSED Settings { /** @brief Is --debug-ignore given? */ bool debugignore{}; + /** @brief Is --debug-ipc given? */ + bool debugipc{}; + /** @brief Internal: Is --debug-lookup or --debug-lookup=all given? */ bool debuglookup{}; diff --git a/test/cli/other_test.py b/test/cli/other_test.py index 4aaddc3572d..72f0a7a00bd 100644 --- a/test/cli/other_test.py +++ b/test/cli/other_test.py @@ -4633,4 +4633,28 @@ def test_dui_include_absolute_missing(tmp_path): # #14675 assert stdout == '' assert stderr.splitlines() == [ f"{test_file}:0:0: error: Can not open include file '/share/include/missing.h' that is explicitly included. [missingIncludeExplicit]" - ] \ No newline at end of file + ] + + +@pytest.mark.xfail(strict=True) # TODO: should not report logChecker when not required +@pytest.mark.skipif(sys.platform == 'win32', reason="requires ProcessExecutor") +def test_ipc_log_checker(tmp_path): + test_file = tmp_path / 'test.c' + with open(test_file, "w") as f: + f.write('void f() {}') + + args = [ + '-q', + '--debug-ipc', + '-j2', + '--executor=process', + str(test_file) + ] + + exitcode, stdout, stderr = cppcheck(args) + assert exitcode == 0 + assert stdout.splitlines() == [ + 'writeToPipe - 5 - 0', + 'handleRead - 5 - 0' + ] + assert stderr.splitlines() == [] \ No newline at end of file diff --git a/test/testcmdlineparser.cpp b/test/testcmdlineparser.cpp index e5d231d47ed..250faaf8d1f 100644 --- a/test/testcmdlineparser.cpp +++ b/test/testcmdlineparser.cpp @@ -498,6 +498,7 @@ class TestCmdlineParser : public TestFixture { TEST_CASE(noSafety); TEST_CASE(noSafetyOverride); TEST_CASE(debugAnalyzerinfo); + TEST_CASE(debugIpc); TEST_CASE(ignorepaths1); TEST_CASE(ignorepaths2); @@ -3479,6 +3480,13 @@ class TestCmdlineParser : public TestFixture { ASSERT_EQUALS(true, settings->debugainfo); } + void debugIpc() { + REDIRECT; + const char * const argv[] = {"cppcheck", "--debug-ipc", "file.cpp"}; + ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parseFromArgs(argv)); + ASSERT_EQUALS(true, settings->debugipc); + } + void ignorepaths1() { REDIRECT; const char * const argv[] = {"cppcheck", "-isrc", "file.cpp"};