From d064f9c24352552e94d7f1f13bdf3b797b2570cb Mon Sep 17 00:00:00 2001 From: "Ryan M. Lederman" Date: Mon, 14 Aug 2023 03:55:32 -0600 Subject: [PATCH] -j 0 causes indefinite hang. require >= 1 (#5326) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In cppcheck 2.11.1 (macOS), using `-j 0` actually causes cppcheck to do nothing–it stalls indefinitely. I could only find one place where `mSettings.jobs` was validated against > 0 and it's simply an assert, so you wouldn't hit it in a release build. - Require -j >= 1 ✅ - Cap -j at 1024, not 10000 ✅ (I don't even know what would happen if you created 10,000 threads, but nothing good; likely exhaust virtual memory or grind the process to a halt). 1024 is still obscene but there may be some hypercomputers out there that have that many logical cores. --- cli/cmdlineparser.cpp | 15 +++++++++++---- test/testcmdlineparser.cpp | 12 ++++++++++-- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index 92b5c6a0a..f7826fef5 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -507,10 +507,17 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) printError("argument to '-j' is not valid - " + err + "."); return false; } - if (tmp > 10000) { - // This limit is here just to catch typos. If someone has - // need for more jobs, this value should be increased. - printError("argument for '-j' is allowed to be 10000 at max."); + if (tmp == 0) { + // TODO: implement get CPU logical core count and use that. + // Usually, -j 0 would mean "use all available cores," but + // if we get a 0, we just stall and don't do any work. + printError("argument for '-j' must be greater than 0."); + return false; + } + if (tmp > 1024) { + // Almost nobody has 1024 logical cores, but somebody out + // there does. + printError("argument for '-j' is allowed to be 1024 at max."); return false; } mSettings.jobs = tmp; diff --git a/test/testcmdlineparser.cpp b/test/testcmdlineparser.cpp index 5fdd05adc..d60006ccd 100644 --- a/test/testcmdlineparser.cpp +++ b/test/testcmdlineparser.cpp @@ -142,6 +142,7 @@ private: TEST_CASE(jobs2); TEST_CASE(jobsMissingCount); TEST_CASE(jobsInvalid); + TEST_CASE(jobsNoJobs); TEST_CASE(jobsTooBig); TEST_CASE(maxConfigs); TEST_CASE(maxConfigsMissingCount); @@ -1010,11 +1011,18 @@ private: ASSERT_EQUALS("cppcheck: error: argument to '-j' is not valid - not an integer.\n", GET_REDIRECT_OUTPUT); } + void jobsNoJobs() { + REDIRECT; + const char * const argv[] = {"cppcheck", "-j0", "file.cpp"}; + ASSERT(!parser->parseFromArgs(3, argv)); + ASSERT_EQUALS("cppcheck: error: argument for '-j' must be greater than 0.\n", GET_REDIRECT_OUTPUT); + } + void jobsTooBig() { REDIRECT; - const char * const argv[] = {"cppcheck", "-j10001", "file.cpp"}; + const char * const argv[] = {"cppcheck", "-j1025", "file.cpp"}; ASSERT(!parser->parseFromArgs(3, argv)); - ASSERT_EQUALS("cppcheck: error: argument for '-j' is allowed to be 10000 at max.\n", GET_REDIRECT_OUTPUT); + ASSERT_EQUALS("cppcheck: error: argument for '-j' is allowed to be 1024 at max.\n", GET_REDIRECT_OUTPUT); } void maxConfigs() {