diff --git a/.github/workflows/CITest.yml b/.github/workflows/CITest.yml index 7be63131bf..89bab89b72 100644 --- a/.github/workflows/CITest.yml +++ b/.github/workflows/CITest.yml @@ -50,7 +50,28 @@ jobs: arch: x64, build-system: 'cmake', diet-build: 'OFF', - enable-asan: 'OFF' + enable-asan: 'OFF', + build_type: 'Debug' + } + - { + name: 'ubuntu-22.04 x64 release - assert warn', + os: ubuntu-22.04, + arch: x64, + build-system: 'cmake', + diet-build: 'OFF', + enable-asan: 'OFF', + build_type: 'Release', + build_options: '-DCAPSTONE_ASSERTION_WARNINGS=ON' + } + - { + name: 'ubuntu-22.04 x64 release - no asserts', + os: ubuntu-22.04, + arch: x64, + build-system: 'cmake', + diet-build: 'OFF', + enable-asan: 'OFF', + build_type: 'Release', + build_options: '-DCAPSTONE_ASSERTION_WARNINGS=OFF' } - { name: 'ubuntu-24.04 x64 ASAN', @@ -58,7 +79,8 @@ jobs: arch: x64, build-system: 'cmake', diet-build: 'OFF', - enable-asan: 'ON' + enable-asan: 'ON', + build_type: 'Debug' } steps: @@ -85,14 +107,16 @@ jobs: if: startsWith(matrix.config.build-system, 'cmake') env: asan: ${{ matrix.config.enable-asan }} + build_option: ${{ matrix.config.build_option }} + build_type: ${{ matrix.config.build_type }} run: | mkdir build && cd build # build static library - cmake -DCAPSTONE_INSTALL=1 -DCMAKE_INSTALL_PREFIX=/usr -DENABLE_ASAN=${asan} -DCAPSTONE_BUILD_DIET=${diet_build} .. - cmake --build . --config Debug + cmake -DCAPSTONE_INSTALL=1 -DCMAKE_INSTALL_PREFIX=/usr -DENABLE_ASAN=${asan} -DCAPSTONE_BUILD_DIET=${diet_build} ${build_option} .. + cmake --build . --config ${build_type} # build shared library - cmake -DCAPSTONE_INSTALL=1 -DCAPSTONE_BUILD_SHARED_LIBS=1 -DCMAKE_INSTALL_PREFIX=/usr -DCAPSTONE_BUILD_CSTEST=ON -DENABLE_ASAN=${asan} .. - sudo cmake --build . --config Debug --target install + cmake -DCAPSTONE_INSTALL=1 -DCAPSTONE_BUILD_SHARED_LIBS=1 -DCMAKE_INSTALL_PREFIX=/usr -DCAPSTONE_BUILD_CSTEST=ON -DENABLE_ASAN=${asan} ${build_option} .. + sudo cmake --build . --config ${build_type} --target install - name: Lower number of KASL randomized address bits run: | diff --git a/CMakeLists.txt b/CMakeLists.txt index bfe5cbf325..6a25c8cd24 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -79,6 +79,7 @@ option(CAPSTONE_USE_DEFAULT_ALLOC "Use default memory allocation functions" ON) option(CAPSTONE_USE_ARCH_REGISTRATION "Use explicit architecture registration" OFF) option(CAPSTONE_ARCHITECTURE_DEFAULT "Whether architectures are enabled by default" ON) option(CAPSTONE_DEBUG "Whether to enable extra debug assertions (enabled with CMAKE_BUILD_TYPE=Debug)" OFF) +option(CAPSTONE_ASSERTION_WARNINGS "Warns about hit assertions in release builds." OFF) option(CAPSTONE_INSTALL "Generate install target" ${PROJECT_IS_TOP_LEVEL}) option(ENABLE_ASAN "Enable address sanitizer" OFF) option(ENABLE_COVERAGE "Enable test coverage" OFF) diff --git a/arch/ARC/ARCGenDisassemblerTables.inc b/arch/ARC/ARCGenDisassemblerTables.inc index 0ebb2b45a6..1a78a76c89 100644 --- a/arch/ARC/ARCGenDisassemblerTables.inc +++ b/arch/ARC/ARCGenDisassemblerTables.inc @@ -1207,7 +1207,7 @@ static const uint8_t DecoderTable64[] = { }; static bool checkDecoderPredicate(MCInst *Inst, unsigned Idx) { - CS_ASSERT_RET_VAL(0 && "Invalid index!", false); + return false; } #define DecodeToMCInst(fname, fieldname, InsnType) \ diff --git a/arch/BPF/BPFDisassembler.c b/arch/BPF/BPFDisassembler.c index dc8538d711..a7a1bf3368 100644 --- a/arch/BPF/BPFDisassembler.c +++ b/arch/BPF/BPFDisassembler.c @@ -539,9 +539,7 @@ static bpf_insn op2insn_st(unsigned opcode, const uint32_t imm) CASE(DW); } - CS_ASSERT_RET_VAL( - false && "Malformed atomic BPF instruction", - BPF_INS_INVALID); + return BPF_INS_INVALID; } #undef CASE diff --git a/cs_priv.h b/cs_priv.h index 476b30703d..cea610dab2 100644 --- a/cs_priv.h +++ b/cs_priv.h @@ -106,6 +106,13 @@ extern cs_vsnprintf_t cs_vsnprintf; /// For the release build the @expr is not included. #ifdef CAPSTONE_DEBUG #define CS_ASSERT(expr) assert(expr) +#elif CAPSTONE_ASSERTION_WARNINGS +#define CS_ASSERT(expr) \ +do { \ + if (!(expr)) { \ + fprintf(stderr, "Capstone hit the assert: \"" #expr "\": %s:%" PRIu32 "\n", __FILE__, __LINE__); \ + } \ +} while(0) #else #define CS_ASSERT(expr) #endif @@ -114,28 +121,32 @@ extern cs_vsnprintf_t cs_vsnprintf; /// In the release build it will check the @expr and return @val if false. #ifdef CAPSTONE_DEBUG #define CS_ASSERT_RET_VAL(expr, val) assert(expr) -#else +#elif CAPSTONE_ASSERTION_WARNINGS #define CS_ASSERT_RET_VAL(expr, val) \ do { \ if (!(expr)) { \ - fprintf(stderr, "Hit assert: " #expr "\n"); \ + fprintf(stderr, "Capstone hit the assert: \"" #expr "\": %s:%" PRIu32 "\n", __FILE__, __LINE__); \ return val; \ } \ } while(0) +#else +#define CS_ASSERT_RET_VAL(expr, val) #endif /// If compiled in debug mode it will assert(@expr). /// In the release build it will check the @expr and return if false. #ifdef CAPSTONE_DEBUG #define CS_ASSERT_RET(expr) assert(expr) -#else +#elif CAPSTONE_ASSERTION_WARNINGS #define CS_ASSERT_RET(expr) \ do { \ if (!(expr)) { \ - fprintf(stderr, "Hit assert: " #expr "\n"); \ + fprintf(stderr, "Capstone hit the assert: \"" #expr "\": %s:%" PRIu32 "\n", __FILE__, __LINE__); \ return; \ } \ } while(0) +#else +#define CS_ASSERT_RET(expr) #endif #endif diff --git a/docs/cs_v6_release_guide.md b/docs/cs_v6_release_guide.md index 1de73b25db..cf2444738b 100644 --- a/docs/cs_v6_release_guide.md +++ b/docs/cs_v6_release_guide.md @@ -90,6 +90,8 @@ For `v7` we can then focus on other big features, like [SAIL](https://github.com - `clang-tidy` is now run on all files changed by a PR. - ASAN: All tests are now run with the address sanitizer enabled. This includes checking for leaks. +- Many more asserts were added. They are only enabled for debug builds (with a few exceptions). + Enabling the option `CAPSTONE_ASSERTION_WARNINGS` for a release build will print warnings but won't abort the program. **Instruction formats for PPC, SystemZ, LoongArch**