From dd1838a7eb527367d88ef0e46b1fd91e0783a8bb Mon Sep 17 00:00:00 2001 From: "Markus F.X.J. Oberhumer" Date: Mon, 21 Aug 2023 22:41:42 +0200 Subject: [PATCH] src: minor cleanups --- .github/workflows/ci.yml | 4 ++-- .../workflows/weekly-ci-cc-alpine-linux.yml | 2 +- .github/workflows/weekly-ci-cc-zigcc.yml | 4 ++-- .github/workflows/weekly-ci-rt-checkers.yml | 5 ++++- Makefile | 1 + src/check/dt_cxxlib.cpp | 9 +++++++++ src/compress/compress.cpp | 6 ++++++ src/file.cpp | 17 +++++++++-------- src/file.h | 8 ++++---- src/util/membuffer.cpp | 19 ++++++++++++------- 10 files changed, 50 insertions(+), 25 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ea8df0a6..58a2524d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,8 +12,8 @@ env: CMAKE_REQUIRED_QUIET: OFF DEBIAN_FRONTEND: noninteractive UPX_CMAKE_BUILD_FLAGS: --verbose - # 2023-08-15 - ZIG_DIST_VERSION: 0.12.0-dev.89+913511557 + # 2023-08-20 + ZIG_DIST_VERSION: 0.12.0-dev.146+020105d0d jobs: job-rebuild-and-verify-stubs: diff --git a/.github/workflows/weekly-ci-cc-alpine-linux.yml b/.github/workflows/weekly-ci-cc-alpine-linux.yml index 30e3abeb..8467f89c 100644 --- a/.github/workflows/weekly-ci-cc-alpine-linux.yml +++ b/.github/workflows/weekly-ci-cc-alpine-linux.yml @@ -17,7 +17,7 @@ on: env: CMAKE_REQUIRED_QUIET: OFF DEBIAN_FRONTEND: noninteractive - UPX_TESTSUITE_LEVEL: 2 + UPX_TESTSUITE_LEVEL: 4 jobs: job-alpine-cmake: # uses cmake + make diff --git a/.github/workflows/weekly-ci-cc-zigcc.yml b/.github/workflows/weekly-ci-cc-zigcc.yml index a009e0ca..ce312bd7 100644 --- a/.github/workflows/weekly-ci-cc-zigcc.yml +++ b/.github/workflows/weekly-ci-cc-zigcc.yml @@ -10,8 +10,8 @@ on: env: CMAKE_REQUIRED_QUIET: OFF DEBIAN_FRONTEND: noninteractive - # 2023-08-15 - ZIG_DIST_VERSION: 0.12.0-dev.89+913511557 + # 2023-08-20 + ZIG_DIST_VERSION: 0.12.0-dev.146+020105d0d jobs: job-linux-zigcc: # uses cmake + make diff --git a/.github/workflows/weekly-ci-rt-checkers.yml b/.github/workflows/weekly-ci-rt-checkers.yml index b20f73c2..af7159c5 100644 --- a/.github/workflows/weekly-ci-rt-checkers.yml +++ b/.github/workflows/weekly-ci-rt-checkers.yml @@ -93,7 +93,10 @@ jobs: export upx_exe_runner="${{ matrix.qemu }}" env -C build/xtarget/clang-static/$release "$PWD"/misc/testsuite/upx_testsuite_1.sh - name: 'Run testsuite clang-static - Valgrind' - if: ${{ true }} # very slow (takes about 30 minutes on current GitHub CI) + if: ${{ true }} # very slow run: | export upx_exe_runner="valgrind --error-exitcode=1 --quiet" + # on current GitHub CI, takes about 30 minutes for release and 80 mins for debug + # reduce time for debug builds + test $release = debug && export UPX_TESTSUITE_LEVEL=4 env -C build/xtarget/clang-static/$release "$PWD"/misc/testsuite/upx_testsuite_1.sh diff --git a/Makefile b/Makefile index 3d52e5e4..1f37586a 100644 --- a/Makefile +++ b/Makefile @@ -212,6 +212,7 @@ build/xtarget/$(UPX_XTARGET)/release: PHONY; $(call run_config_and_build,$@,Rele build/xtarget/$(UPX_XTARGET)/%: export CC build/xtarget/$(UPX_XTARGET)/%: export CXX # shortcuts +xtarget/all: xtarget/debug xtarget/release xtarget/debug: build/xtarget/$(UPX_XTARGET)/debug xtarget/release: build/xtarget/$(UPX_XTARGET)/release # set new default diff --git a/src/check/dt_cxxlib.cpp b/src/check/dt_cxxlib.cpp index dd36a38c..41cb6669 100644 --- a/src/check/dt_cxxlib.cpp +++ b/src/check/dt_cxxlib.cpp @@ -114,6 +114,14 @@ struct TestTriBool { static_assert(std::is_nothrow_destructible::value); static_assert(std::is_standard_layout::value); static_assert(std::is_trivially_copyable::value); + static_assert(sizeof(typename T::value_type) == sizeof(typename T::underlying_type)); + static_assert(alignof(typename T::value_type) == alignof(typename T::underlying_type)); +#if (ACC_ARCH_M68K && ACC_OS_TOS && ACC_CC_GNUC) && defined(__MINT__) + // broken compiler +#else + static_assert(sizeof(T) == sizeof(typename T::underlying_type)); + static_assert(alignof(T) == alignof(typename T::underlying_type)); +#endif static_assert(T(false) == T::False); static_assert(T(true) == T::True); static_assert(T(T::False) == T::False); @@ -123,6 +131,7 @@ struct TestTriBool { static_assert(array[0].isStrictFalse()); static_assert(array[1].isStrictTrue()); static_assert(array[2].isThird()); + static_assert(sizeof(array) == 3 * sizeof(T)); T a; CHECK(!a); CHECK(a.isStrictFalse()); diff --git a/src/compress/compress.cpp b/src/compress/compress.cpp index 2badaccf..be480d8c 100644 --- a/src/compress/compress.cpp +++ b/src/compress/compress.cpp @@ -92,6 +92,7 @@ int upx_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned cresult->debug.c_len = 0; #endif + const unsigned orig_dst_len = *dst_len; if (__acc_cte(false)) { } #if (WITH_LZMA) @@ -118,6 +119,7 @@ int upx_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned // debugging aid cresult->debug.c_len = *dst_len; #endif + assert_noexcept(*dst_len <= orig_dst_len); return r; } @@ -135,6 +137,7 @@ int upx_decompress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigne if (cresult && cresult->debug.method == 0) cresult = nullptr; + const unsigned orig_dst_len = *dst_len; if (__acc_cte(false)) { } #if (WITH_LZMA) @@ -161,6 +164,7 @@ int upx_decompress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigne throwInternalError("unknown decompression method"); } + assert_noexcept(*dst_len <= orig_dst_len); return r; } @@ -180,6 +184,7 @@ int upx_test_overlap(const upx_bytep buf, const upx_bytep tbuf, unsigned src_off unsigned overlap_overhead = src_off + src_len - *dst_len; assert((int) overlap_overhead > 0); + const unsigned orig_dst_len = *dst_len; if (__acc_cte(false)) { } #if (WITH_LZMA) @@ -202,6 +207,7 @@ int upx_test_overlap(const upx_bytep buf, const upx_bytep tbuf, unsigned src_off throwInternalError("unknown decompression method"); } + assert_noexcept(*dst_len <= orig_dst_len); return r; } diff --git a/src/file.cpp b/src/file.cpp index 94b6850a..b07fcc80 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -66,9 +66,10 @@ FileBase::~FileBase() may_throw { fprintf(stderr,"%s: %s\n", _name, __PRETTY_FUNCTION__); #endif - // FIXME: we should use close() during exception unwinding but - // closex() otherwise - closex(); + if (std::uncaught_exceptions() == 0) + closex(); // may_throw + else + close_noexcept(); // currently in exception unwinding, use noexcept variant } bool FileBase::do_sopen() { @@ -93,7 +94,7 @@ bool FileBase::do_sopen() { return true; } -bool FileBase::close() noexcept { +bool FileBase::close_noexcept() noexcept { bool ok = true; if (isOpen() && _fd != STDIN_FILENO && _fd != STDOUT_FILENO && _fd != STDERR_FILENO) if (::close(_fd) == -1) @@ -108,7 +109,7 @@ bool FileBase::close() noexcept { } void FileBase::closex() may_throw { - if (!close()) + if (!close_noexcept()) throwIOException("close failed", errno); } @@ -156,7 +157,7 @@ upx_off_t FileBase::st_size() const { return _length; } **************************************************************************/ void InputFile::sopen(const char *name, int flags, int shflags) { - close(); + closex(); _name = name; _flags = flags; _shflags = shflags; @@ -206,7 +207,7 @@ upx_off_t InputFile::st_size_orig() const { return _length_orig; } **************************************************************************/ void OutputFile::sopen(const char *name, int flags, int shflags, int mode) { - close(); + closex(); _name = name; _flags = flags; _shflags = shflags; @@ -228,7 +229,7 @@ void OutputFile::sopen(const char *name, int flags, int shflags, int mode) { } bool OutputFile::openStdout(int flags, bool force) { - close(); + closex(); int fd = STDOUT_FILENO; if (!force && acc_isatty(fd)) return false; diff --git a/src/file.h b/src/file.h index 5665e2d2..1584b947 100644 --- a/src/file.h +++ b/src/file.h @@ -37,11 +37,11 @@ protected: virtual ~FileBase() may_throw; public: - bool close() noexcept; + bool close_noexcept() noexcept; void closex() may_throw; - bool isOpen() const { return _fd >= 0; } - int getFd() const { return _fd; } - const char *getName() const { return _name; } + bool isOpen() const noexcept { return _fd >= 0; } + int getFd() const noexcept { return _fd; } + const char *getName() const noexcept { return _name; } virtual upx_off_t seek(upx_off_t off, int whence); upx_off_t tell() const; diff --git a/src/util/membuffer.cpp b/src/util/membuffer.cpp index 001af9ff..6ea80a89 100644 --- a/src/util/membuffer.cpp +++ b/src/util/membuffer.cpp @@ -205,13 +205,18 @@ void MemBuffer::dealloc() noexcept { debug_set(debug.last_return_address_dealloc, upx_return_address()); #if DEBUG || 1 // info: calling checkState() here violates "noexcept", so we need a try block - try { - checkState(); - } catch (const Throwable &e) { - printErr("unknown", e); - std::terminate(); - } catch (...) { - std::terminate(); + bool shall_check = true; + // bool shall_check = (std::uncaught_exceptions() == 0); // only if not unwinding + // TODO later: add a priority() method to class Throwable + if (shall_check) { + try { + checkState(); + } catch (const Throwable &e) { + printErr("unknown", e); + std::terminate(); + } catch (...) { + std::terminate(); + } } #endif stats.global_dealloc_counter += 1;