some `--exception-handling` related improvements (#4368)

This commit is contained in:
Oliver Stöneberg 2022-08-20 20:54:31 +02:00 committed by GitHub
parent b04bf7396f
commit 1202efb438
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 123 additions and 15 deletions

View File

@ -640,7 +640,7 @@ test/testclangimport.o: test/testclangimport.cpp lib/clangimport.h lib/color.h l
test/testclass.o: test/testclass.cpp externals/tinyxml2/tinyxml2.h lib/check.h lib/checkclass.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h test/testsuite.h
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/testclass.o test/testclass.cpp
test/testcmdlineparser.o: test/testcmdlineparser.cpp cli/cmdlineparser.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/utils.h test/redirect.h test/testsuite.h
test/testcmdlineparser.o: test/testcmdlineparser.cpp cli/cmdlineparser.h cli/cppcheckexecutor.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/utils.h test/redirect.h test/testsuite.h
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CPPFILESDIR) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -c -o test/testcmdlineparser.o test/testcmdlineparser.cpp
test/testcondition.o: test/testcondition.cpp externals/simplecpp/simplecpp.h externals/tinyxml2/tinyxml2.h lib/check.h lib/checkcondition.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h test/testsuite.h

View File

@ -242,11 +242,13 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[])
mSettings->addEnabled("information");
}
else if (std::strncmp(argv[i], "--clang", 7) == 0) {
else if (std::strcmp(argv[i], "--clang") == 0) {
mSettings->clang = true;
if (std::strncmp(argv[i], "--clang=", 8) == 0) {
mSettings->clangExecutable = argv[i] + 8;
}
}
else if (std::strncmp(argv[i], "--clang=", 8) == 0) {
mSettings->clang = true;
mSettings->clangExecutable = argv[i] + 8;
}
else if (std::strncmp(argv[i], "--config-exclude=",17) ==0) {
@ -339,14 +341,19 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[])
}
// Exception handling inside cppcheck client
else if (std::strcmp(argv[i], "--exception-handling") == 0)
else if (std::strcmp(argv[i], "--exception-handling") == 0) {
mSettings->exceptionHandling = true;
}
// TODO: only applied with Signal handling i.e. Linux
// Exception handling inside cppcheck client
else if (std::strncmp(argv[i], "--exception-handling=", 21) == 0) {
const std::string exceptionOutfilename = argv[i] + 21;
if (exceptionOutfilename != "stderr" && exceptionOutfilename != "stdout") {
printError("invalid '--exception-handling' argument");
return false;
}
mSettings->exceptionHandling = true;
const std::string exceptionOutfilename = &(argv[i][21]);
CppCheckExecutor::setExceptionOutput((exceptionOutfilename=="stderr") ? stderr : stdout);
CppCheckExecutor::setExceptionOutput((exceptionOutfilename == "stderr") ? stderr : stdout);
}
// Filter errors

View File

@ -165,9 +165,8 @@ namespace {
/*
* Any evaluation of the exception needs to be done here!
*/
int filterException(int code, PEXCEPTION_POINTERS ex)
int filterException(FILE *outputFile, int code, PEXCEPTION_POINTERS ex)
{
FILE *outputFile = stdout;
fputs("Internal error: ", outputFile);
switch (ex->ExceptionRecord->ExceptionCode) {
case EXCEPTION_ACCESS_VIOLATION:
@ -256,11 +255,10 @@ namespace {
*/
int check_wrapper_seh(CppCheckExecutor& executor, int (CppCheckExecutor::*f)(CppCheck&), CppCheck& cppcheck)
{
FILE *outputFile = stdout;
FILE *outputFile = CppCheckExecutor::getExceptionOutput();
__try {
return (&executor->*f)(cppcheck);
} __except (filterException(GetExceptionCode(), GetExceptionInformation())) {
// reporting to stdout may not be helpful within a GUI application...
} __except (filterException(outputFile, GetExceptionCode(), GetExceptionInformation())) {
fputs("Please report this to the cppcheck developers!\n", outputFile);
return -1;
}

View File

@ -40,5 +40,17 @@ if (MSVC AND DISABLE_CRTDBG_MAP_ALLOC)
add_definitions(-DDISABLE_CRTDBG_MAP_ALLOC)
endif()
if (NO_UNIX_SIGNAL_HANDLING)
add_definitions(-DNO_UNIX_SIGNAL_HANDLING)
endif()
if (NO_UNIX_BACKTRACE_SUPPORT)
add_definitions(-DNO_UNIX_BACKTRACE_SUPPORT)
endif()
if (NO_WINDOWS_SEH)
add_definitions(-DNO_WINDOWS_SEH)
endif()
file(TO_CMAKE_PATH ${FILESDIR} _filesdir)
add_definitions(-DFILESDIR="${_filesdir}")

View File

@ -45,7 +45,11 @@ option(USE_BUNDLED_TINYXML2 "Usage of bundled tinyxml2 library"
option(CPPCHK_GLIBCXX_DEBUG "Usage of _GLIBCXX_DEBUG in Debug build" ON)
option(USE_THREADS "Usage of threads instead of fork() for -j" OFF)
option(USE_BOOST "Usage of Boost" OFF)
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)
option(NO_WINDOWS_SEH "Disable usage of Windows SEH" OFF)
if (CMAKE_VERSION VERSION_EQUAL "3.16" OR CMAKE_VERSION VERSION_GREATER "3.16")
set(CMAKE_DISABLE_PRECOMPILE_HEADERS Off CACHE BOOL "Disable precompiled headers")

View File

@ -28,6 +28,11 @@ message( STATUS )
message( STATUS "USE_MATCHCOMPILER = ${USE_MATCHCOMPILER}" )
message( STATUS "USE_MATCHCOMPILER_OPT = ${USE_MATCHCOMPILER_OPT}" )
message( STATUS )
message( STATUS "DISABLE_CRTDBG_MAP_ALLOC = ${DISABLE_CRTDBG_MAP_ALLOC}")
message( STATUS "NO_UNIX_SIGNAL_HANDLING = ${NO_UNIX_SIGNAL_HANDLING}")
message( STATUS "NO_UNIX_BACKTRACE_SUPPORT = ${NO_UNIX_BACKTRACE_SUPPORT}")
message( STATUS "NO_WINDOWS_SEH = ${NO_WINDOWS_SEH}")
message( STATUS )
if(NOT DEFINED BUILD_SHARED_LIBS)
message( STATUS "BUILD_SHARED_LIBS = OFF" )
else()

View File

@ -131,7 +131,7 @@ static const std::string emptyString;
#define SUPPRESS_FLOAT_EQUAL_WARNING(...) __VA_ARGS__
#endif
#if defined(_WIN32) && defined(_MSC_VER)
#if !defined(NO_WINDOWS_SEH) && defined(_WIN32) && defined(_MSC_VER)
#define USE_WINDOWS_SEH
#endif

View File

@ -2,3 +2,5 @@ release notes for cppcheck-2.9
- restored check for negative allocation (new[]) and negative VLA sizes from cppcheck 1.87 (LCppC backport)
- replaced hardcoded check for pipe() buffer size by library configuration option (LCppC backport)
- on Windows the callstack is now being written to the output specific via "--exception-handling"
- make it possible to disable the various exception handling parts via the CMake options "NO_UNIX_SIGNAL_HANDLING", "NO_UNIX_BACKTRACE_SUPPORT" and "NO_WINDOWS_SEH"

View File

@ -17,6 +17,7 @@
*/
#include "cmdlineparser.h"
#include "cppcheckexecutor.h"
#include "errortypes.h"
#include "platform.h"
#include "redirect.h"
@ -131,6 +132,14 @@ private:
TEST_CASE(errorlistverbose1);
TEST_CASE(errorlistverbose2);
TEST_CASE(ignorepathsnopath);
TEST_CASE(exceptionhandling);
TEST_CASE(exceptionhandling2);
TEST_CASE(exceptionhandling3);
TEST_CASE(exceptionhandlingInvalid);
TEST_CASE(exceptionhandlingInvalid2);
TEST_CASE(clang);
TEST_CASE(clang2);
TEST_CASE(clangInvalid);
// TODO
// Disabling these tests since they use relative paths to the
@ -965,6 +974,77 @@ private:
ASSERT_EQUALS(0, parser.getIgnoredPaths().size());
}
void exceptionhandling() {
REDIRECT;
const char * const argv[] = {"cppcheck", "--exception-handling"};
settings.exceptionHandling = false;
CppCheckExecutor::setExceptionOutput(stderr);
ASSERT(defParser.parseFromArgs(2, argv));
ASSERT(settings.exceptionHandling);
ASSERT_EQUALS(stderr, CppCheckExecutor::getExceptionOutput());
}
void exceptionhandling2() {
REDIRECT;
const char * const argv[] = {"cppcheck", "--exception-handling=stderr"};
settings.exceptionHandling = false;
CppCheckExecutor::setExceptionOutput(stdout);
ASSERT(defParser.parseFromArgs(2, argv));
ASSERT(settings.exceptionHandling);
ASSERT_EQUALS(stderr, CppCheckExecutor::getExceptionOutput());
}
void exceptionhandling3() {
REDIRECT;
const char * const argv[] = {"cppcheck", "--exception-handling=stdout"};
settings.exceptionHandling = false;
CppCheckExecutor::setExceptionOutput(stderr);
ASSERT(defParser.parseFromArgs(2, argv));
ASSERT(settings.exceptionHandling);
ASSERT_EQUALS(stdout, CppCheckExecutor::getExceptionOutput());
}
void exceptionhandlingInvalid() {
REDIRECT;
const char * const argv[] = {"cppcheck", "--exception-handling=exfile"};
ASSERT_EQUALS(false, defParser.parseFromArgs(2, argv));
ASSERT_EQUALS("cppcheck: error: invalid '--exception-handling' argument\n", GET_REDIRECT_OUTPUT);
}
void exceptionhandlingInvalid2() {
REDIRECT;
const char * const argv[] = {"cppcheck", "--exception-handling-foo"};
ASSERT_EQUALS(false, defParser.parseFromArgs(2, argv));
ASSERT_EQUALS("cppcheck: error: unrecognized command line option: \"--exception-handling-foo\".\n", GET_REDIRECT_OUTPUT);
}
void clang() {
REDIRECT;
const char * const argv[] = {"cppcheck", "--clang"};
settings.clang = false;
settings.clangExecutable = "exe";
ASSERT(defParser.parseFromArgs(2, argv));
ASSERT(settings.clang);
ASSERT_EQUALS("exe", settings.clangExecutable);
}
void clang2() {
REDIRECT;
const char * const argv[] = {"cppcheck", "--clang=clang-14"};
settings.clang = false;
settings.clangExecutable = "";
ASSERT(defParser.parseFromArgs(2, argv));
ASSERT(settings.clang);
ASSERT_EQUALS("clang-14", settings.clangExecutable);
}
void clangInvalid() {
REDIRECT;
const char * const argv[] = {"cppcheck", "--clang-foo"};
ASSERT_EQUALS(false, defParser.parseFromArgs(2, argv));
ASSERT_EQUALS("cppcheck: error: unrecognized command line option: \"--clang-foo\".\n", GET_REDIRECT_OUTPUT);
}
/*
void ignorepaths1() {
REDIRECT;