diff --git a/.github/workflows/address-sanitizer.yml b/.github/workflows/address-sanitizer.yml deleted file mode 100644 index 7fd3cde12..000000000 --- a/.github/workflows/address-sanitizer.yml +++ /dev/null @@ -1,38 +0,0 @@ -# Note: This is duplicated from thread-sanitizer.yml in order to keep the ci running if one of both sanitizers fail -name: Address Sanitizer Test - -on: - workflow_dispatch: - pull_request: - push: - tags: - - 'v*.*.*' - branches: - - master - - develop - -concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: true - -jobs: - linux-address-sanitizer-gcc: - name: Linux GCC Address Sanitizer Test - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - image: ["debian:bookworm-slim", "debian:bullseye-slim", "ubuntu:kinetic"] - env: - SANITIZER_SKIP_SUMMARY: 1 - - steps: - - name: Check out the repository - uses: actions/checkout@v2 - with: - fetch-depth: 0 - - - name: Install, build and run sanitizer tests - run: ./docker-compose.sh test-address-sanitizer - env: - METACALL_BASE_IMAGE: ${{ matrix.image }} diff --git a/.github/workflows/thread-sanitizer.yml b/.github/workflows/linux-sanitizer.yml similarity index 73% rename from .github/workflows/thread-sanitizer.yml rename to .github/workflows/linux-sanitizer.yml index 14c296b00..5b4063300 100644 --- a/.github/workflows/thread-sanitizer.yml +++ b/.github/workflows/linux-sanitizer.yml @@ -1,5 +1,4 @@ -# Note: This is duplicated from address-sanitizer.yml in order to keep the ci running if one of both sanitizers fail -name: Thread Sanitizer Test +name: Linux Sanitizer Test on: workflow_dispatch: @@ -17,12 +16,15 @@ concurrency: jobs: linux-sanitizer-gcc: - name: Linux GCC Thread Sanitizer Test + name: Linux GCC Sanitizer Test runs-on: ubuntu-latest + strategy: fail-fast: false matrix: image: ["debian:bookworm-slim", "debian:bullseye-slim", "ubuntu:kinetic"] + sanitizer: [address-sanitizer, thread-sanitizer] # TODO: memory-sanitizer not supported by GCC + env: SANITIZER_SKIP_SUMMARY: 1 @@ -33,6 +35,7 @@ jobs: fetch-depth: 0 - name: Install, build and run thread sanitizer tests - run: ./docker-compose.sh test-thread-sanitizer + run: ./docker-compose.sh test-${{ matrix.sanitizer }} env: + METACALL_BUILD_TYPE: debug METACALL_BASE_IMAGE: ${{ matrix.image }} diff --git a/.github/workflows/linux-test.yml b/.github/workflows/linux-test.yml index 279216f2a..688ac126d 100644 --- a/.github/workflows/linux-test.yml +++ b/.github/workflows/linux-test.yml @@ -24,12 +24,6 @@ jobs: build: [debug, release] image: ["debian:bookworm-slim", "debian:bullseye-slim", "ubuntu:kinetic"] # TODO: "alpine:3.17" - env: - DEBIAN_FRONTEND: noninteractive - LTTNG_UST_REGISTER_TIMEOUT: 0 - NUGET_XMLDOC_MODE: skip - DOTNET_CLI_TELEMETRY_OPTOUT: 'true' - steps: - name: Check out the repository uses: actions/checkout@v2 diff --git a/.github/workflows/macos-test.yml b/.github/workflows/macos-test.yml index 850214c8a..c3877315e 100644 --- a/.github/workflows/macos-test.yml +++ b/.github/workflows/macos-test.yml @@ -26,7 +26,6 @@ jobs: {build: debug, sanitizer: without-sanitizer}, {build: debug, sanitizer: address-sanitizer}, {build: debug, sanitizer: thread-sanitizer}, - {build: debug, sanitizer: ub-sanitizer}, {build: release, sanitizer: without-sanitizer} ] diff --git a/.github/workflows/windows-test.yml b/.github/workflows/windows-test.yml index c8c9b263b..64394a2a1 100644 --- a/.github/workflows/windows-test.yml +++ b/.github/workflows/windows-test.yml @@ -25,9 +25,9 @@ jobs: options: [ {build: debug, sanitizer: without-sanitizer}, {build: debug, sanitizer: address-sanitizer}, - {build: debug, sanitizer: thread-sanitizer}, - {build: debug, sanitizer: memory-sanitizer}, - {build: debug, sanitizer: ub-sanitizer}, + # TODO: Not supported yet + # {build: debug, sanitizer: thread-sanitizer}, + # {build: debug, sanitizer: memory-sanitizer}, # TODO: Release build not working {build: release, sanitizer: without-sanitizer} ] diff --git a/cmake/CompileOptions.cmake b/cmake/CompileOptions.cmake index 2fb5bcfc2..8fc637211 100644 --- a/cmake/CompileOptions.cmake +++ b/cmake/CompileOptions.cmake @@ -3,9 +3,8 @@ # option(OPTION_BUILD_ADDRESS_SANITIZER "Build with sanitizer compiler options." OFF) -option(OPTION_BUILD_MEMORY_SANITIZER "Build with memory sanitizer compiler options." OFF) option(OPTION_BUILD_THREAD_SANITIZER "Build with thread sanitizer compiler options." OFF) -option(OPTION_BUILD_UB_SANITIZER "Build with undefined behavior sanitizer compiler options." OFF) +option(OPTION_BUILD_MEMORY_SANITIZER "Build with memory sanitizer compiler options." OFF) if((OPTION_BUILD_ADDRESS_SANITIZER AND OPTION_BUILD_MEMORY_SANITIZER) OR (OPTION_BUILD_ADDRESS_SANITIZER AND OPTION_BUILD_THREAD_SANITIZER) OR (OPTION_BUILD_MEMORY_SANITIZER AND OPTION_BUILD_THREAD_SANITIZER)) message(FATAL_ERROR "OPTION_BUILD_ADDRESS_SANITIZER and OPTION_BUILD_MEMORY_SANITIZER and OPTION_BUILD_THREAD_SANITIZER are mutually exclusive, choose one of them") @@ -85,15 +84,6 @@ elseif(OPTION_BUILD_MEMORY_SANITIZER AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "Cla set(SANITIZER_COMPILE_DEFINITIONS "__MEMORY_SANITIZER__=1" ) -elseif(OPTION_BUILD_UB_SANITIZER AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")) - # TODO - set(SANITIZER_LIBRARIES) - set(TESTS_SANITIZER_ENVIRONMENT_VARIABLES - "UBSAN_OPTIONS=print_stacktrace=1" - ) - set(SANITIZER_COMPILE_DEFINITIONS - "__UB_SANITIZER__=1" - ) elseif(OPTION_BUILD_ADDRESS_SANITIZER AND (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")) set(SANITIZER_LIBRARIES -lasan -lubsan) set(TESTS_SANITIZER_ENVIRONMENT_VARIABLES @@ -237,17 +227,16 @@ if(WIN32 AND MSVC) # Sanitizers if(OPTION_BUILD_THREAD_SANITIZER AND (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")) add_compile_options(/fsanitize=thread) + # add_compile_options(/fsanitize=undefined) add_link_options(/INCREMENTAL:NO) elseif(OPTION_BUILD_ADDRESS_SANITIZER AND (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")) add_compile_options(/fsanitize=address) + # add_compile_options(/fsanitize=undefined) add_link_options(/INCREMENTAL:NO) elseif(OPTION_BUILD_MEMORY_SANITIZER AND (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")) add_compile_options(/fsanitize=memory) add_compile_options(/fsanitize=leak) add_link_options(/INCREMENTAL:NO) - elseif(OPTION_BUILD_UB_SANITIZER AND (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")) - add_compile_options(/fsanitize=undefined) - add_link_options(/INCREMENTAL:NO) endif() endif() @@ -286,6 +275,10 @@ if (PROJECT_OS_FAMILY MATCHES "unix" OR PROJECT_OS_FAMILY MATCHES "macos") add_compile_options(-fsanitize=undefined) add_compile_options(-fsanitize=address) add_compile_options(-fsanitize-address-use-after-scope) + add_compile_options(-fsanitize=float-divide-by-zero) + add_compile_options(-fsanitize=float-cast-overflow) + add_compile_options(-fsanitize=pointer-compare) + add_compile_options(-fsanitize=pointer-subtract) if(PROJECT_OS_FAMILY MATCHES "unix") if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") add_compile_options(-fuse-ld=gold) @@ -310,8 +303,6 @@ if (PROJECT_OS_FAMILY MATCHES "unix" OR PROJECT_OS_FAMILY MATCHES "macos") add_link_options(-fsanitize-memory-track-origins) add_link_options(-fsanitize-memory-use-after-dtor) endif() - elseif(OPTION_BUILD_UB_SANITIZER AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")) - # TODO endif() # Debug symbols diff --git a/docker-compose.sh b/docker-compose.sh index 64a6a4933..3d1ed0ad2 100755 --- a/docker-compose.sh +++ b/docker-compose.sh @@ -91,8 +91,8 @@ sub_test() { docker-compose -f docker-compose.yml -f docker-compose.test.yml build --force-rm dev } -# Build MetaCall Docker Compose with Address Sanitizer for testing (link manually dockerignore files) -sub_test_address_sanitizer() { +# Build MetaCall Docker Compose with Sanitizer for testing (link manually dockerignore files) +sub_test_sanitizer() { # Disable BuildKit as workaround due to log limits (TODO: https://github.com/docker/buildx/issues/484) export DOCKER_BUILDKIT=0 @@ -142,15 +142,6 @@ sub_test_address_sanitizer() { fi } -# Build MetaCall Docker Compose with Thread Sanitizer for testing (link manually dockerignore files) -sub_test_thread_sanitizer() { - # Enable build with thread sanitizer - export METACALL_BUILD_SANITIZER="thread-sanitizer" - - # Run tests with thread sanitizer - sub_test_address_sanitizer -} - # Build MetaCall Docker Compose with caching (link manually dockerignore files) sub_cache() { if [ -z "$IMAGE_REGISTRY" ]; then @@ -268,6 +259,7 @@ sub_help() { echo " test" echo " test-address-sanitizer" echo " test-thread-sanitizer" + echo " test-memory-sanitizer" echo " cache" echo " push" echo " pack" @@ -288,10 +280,16 @@ case "$1" in sub_test ;; test-address-sanitizer) - sub_test_address_sanitizer + export METACALL_BUILD_SANITIZER="address-sanitizer" + sub_test_sanitizer ;; test-thread-sanitizer) - sub_test_thread_sanitizer + export METACALL_BUILD_SANITIZER="thread-sanitizer" + sub_test_sanitizer + ;; + test-memory-sanitizer) + export METACALL_BUILD_SANITIZER="memory-sanitizer" + sub_test_sanitizer ;; cache) sub_cache diff --git a/docs/README.md b/docs/README.md index 6f9c2eb78..863494524 100644 --- a/docs/README.md +++ b/docs/README.md @@ -708,9 +708,8 @@ For debugging memory leaks, undefined behaviors and other related problems, the | :--------------------------------: | -------------------------------------------------------------- | :-----------: | | **OPTION_TEST_MEMORYCHECK** | Enable Valgrind with memcheck tool for the tests. | OFF | | **OPTION_BUILD_ADDRESS_SANITIZER** | Build with AddressSanitizer family (GCC, Clang and MSVC). | OFF | -| **OPTION_BUILD_MEMORY_SANITIZER** | Build with MemorySanitizer family (Clang and MSVC). | OFF | | **OPTION_BUILD_THREAD_SANITIZER** | Build with ThreadSanitizer family (GCC, Clang and MSVC). | OFF | -| **OPTION_BUILD_UB_SANITIZER** | Build with UndefinedBehaviorSanitizer family (Clang and MSVC). | OFF | +| **OPTION_BUILD_MEMORY_SANITIZER** | Build with MemorySanitizer family (Clang and MSVC). | OFF | All options are mutually exclusive. Valgrind is not compatible with AddressSanitizer and AddressSanitizer is not compatible with ThreadSanitizer and AddressSanitizer with MemorySanitizer. Some run-times may fail if they are not compiled with AddressSanitizer too, for example NetCore. Due to this, tests implying may fail with signal 11. The same problem happens with Valgrind, due to that, some tests are excluded of the memcheck target. diff --git a/source/dynlink/source/dynlink_impl_beos.c b/source/dynlink/source/dynlink_impl_beos.c index f8f0940d7..9170b9166 100644 --- a/source/dynlink/source/dynlink_impl_beos.c +++ b/source/dynlink/source/dynlink_impl_beos.c @@ -94,7 +94,7 @@ int dynlink_impl_interface_unload_beos(dynlink handle, dynlink_impl impl) { (void)handle; -#if defined(__ADDRESS_SANITIZER__) || defined(__THREAD_SANITIZER__) || defined(__MEMORY_SANITIZER__) || defined(__UB_SANITIZER__) +#if defined(__ADDRESS_SANITIZER__) || defined(__THREAD_SANITIZER__) || defined(__MEMORY_SANITIZER__) /* Disable dlclose when running with address sanitizer in order to maintain stacktraces */ (void)impl; return 0; diff --git a/source/dynlink/source/dynlink_impl_unix.c b/source/dynlink/source/dynlink_impl_unix.c index d488b263e..40fb3b9a9 100644 --- a/source/dynlink/source/dynlink_impl_unix.c +++ b/source/dynlink/source/dynlink_impl_unix.c @@ -114,7 +114,7 @@ int dynlink_impl_interface_unload_unix(dynlink handle, dynlink_impl impl) { (void)handle; -#if defined(__ADDRESS_SANITIZER__) || defined(__THREAD_SANITIZER__) || defined(__MEMORY_SANITIZER__) || defined(__UB_SANITIZER__) +#if defined(__ADDRESS_SANITIZER__) || defined(__THREAD_SANITIZER__) || defined(__MEMORY_SANITIZER__) /* Disable dlclose when running with address sanitizer in order to maintain stacktraces */ (void)impl; return 0; diff --git a/source/loaders/java_loader/bootstrap/lib/bootstrap.java b/source/loaders/java_loader/bootstrap/lib/bootstrap.java index 62c39195c..8ac33814f 100644 --- a/source/loaders/java_loader/bootstrap/lib/bootstrap.java +++ b/source/loaders/java_loader/bootstrap/lib/bootstrap.java @@ -16,8 +16,6 @@ import java.nio.file.Path; import java.nio.file.Paths; -// TODO: Review this: https://www.codeproject.com/Tips/1129615/JNI-Signature-for-Java-Method - public class bootstrap { private static Set executionPath = new HashSet(); @@ -143,8 +141,8 @@ public static Class[] load_from_package(String path) { JarFile jarFile = new JarFile(curJarPath.toString()); Enumeration e = jarFile.entries(); - Path jpath = Paths.get("jar:file:", curExecPath, path); - String jarPath = jpath.toString() + "!/"; + Path jpath = Paths.get(curExecPath, path); + String jarPath = "jar:file:" + jpath.toString().replace("\\", "/") + "!/"; Path epath = Paths.get(curExecPath, path); executionPath.add(epath.toString()); @@ -157,7 +155,7 @@ public static Class[] load_from_package(String path) { if (je.getName().endsWith(".class")) { String className = je.getName().substring(0, je.getName().length() - 6); - className = className.replace(File.separatorChar, '.'); + className = className.replace('/', '.'); try { Class c = clsLoader.loadClass(className); @@ -213,25 +211,43 @@ private static String[] getTypeSignature(Class t) { return new String[] { name, primitive ? "L" + signature + ";" : signature }; } - public static String getSignature(Method m) { - String sig; - try { - Field gSig = Method.class.getDeclaredField("signature"); - gSig.setAccessible(true); - sig = (String) gSig.get(m); - if (sig != null) - return sig; - } catch (IllegalAccessException | NoSuchFieldException e) { - e.printStackTrace(); - } - - StringBuilder sb = new StringBuilder("("); + // Holds a mapping from Java type names to native type codes + private static final Map, String> PRIMITIVE_TO_SIGNATURE; + static { + PRIMITIVE_TO_SIGNATURE = new HashMap, String>(9); + PRIMITIVE_TO_SIGNATURE.put(byte.class, "B"); + PRIMITIVE_TO_SIGNATURE.put(char.class, "C"); + PRIMITIVE_TO_SIGNATURE.put(short.class, "S"); + PRIMITIVE_TO_SIGNATURE.put(int.class, "I"); + PRIMITIVE_TO_SIGNATURE.put(long.class, "J"); + PRIMITIVE_TO_SIGNATURE.put(float.class, "F"); + PRIMITIVE_TO_SIGNATURE.put(double.class, "D"); + PRIMITIVE_TO_SIGNATURE.put(void.class, "V"); + PRIMITIVE_TO_SIGNATURE.put(boolean.class, "Z"); + } - for (Class c : m.getParameterTypes()) - sb.append((sig = Array.newInstance(c, 0).toString()).substring(1, sig.indexOf('@'))); + // Returns the internal name of {@code clazz} (also known as the descriptor) + private static String getSignature(Class clazz) { + String primitiveSignature = PRIMITIVE_TO_SIGNATURE.get(clazz); + if (primitiveSignature != null) { + return primitiveSignature; + } else if (clazz.isArray()) { + return "[" + getSignature(clazz.getComponentType()); + } else { + return "L" + clazz.getName().replace('.', '/') + ";"; + } + } - return sb.append(')').append(m.getReturnType() == void.class ? "V" - : (sig = Array.newInstance(m.getReturnType(), 0).toString()).substring(1, sig.indexOf('@'))).toString(); + public static String getSignature(Method m) { + StringBuilder result = new StringBuilder(); + result.append('('); + Class[] parameterTypes = m.getParameterTypes(); + for (Class parameterType : parameterTypes) { + result.append(getSignature(parameterType)); + } + result.append(')'); + result.append(getSignature(m.getReturnType())); + return result.toString(); } public static String get_Field_Type(Class cls, String key) { diff --git a/source/portability/source/portability_path.c b/source/portability/source/portability_path.c index 5e42ad2ad..31ed52060 100644 --- a/source/portability/source/portability_path.c +++ b/source/portability/source/portability_path.c @@ -449,7 +449,7 @@ int portability_path_separator_normalize_inplace(char *path, size_t size) { if (separator == 0) { - separator = path[iterator]; + separator = PORTABILITY_PATH_SEPARATOR_C; /* Use current platform style as default */ } else { diff --git a/source/ports/go_port/CMakeLists.txt b/source/ports/go_port/CMakeLists.txt index 641d8e3d7..51c55d8ab 100644 --- a/source/ports/go_port/CMakeLists.txt +++ b/source/ports/go_port/CMakeLists.txt @@ -42,7 +42,7 @@ add_custom_target(${target} # Define test # -if(OPTION_BUILD_ADDRESS_SANITIZER OR OPTION_BUILD_THREAD_SANITIZER OR OPTION_BUILD_MEMORY_SANITIZER OR OPTION_BUILD_UB_SANITIZER) +if(OPTION_BUILD_ADDRESS_SANITIZER OR OPTION_BUILD_THREAD_SANITIZER OR OPTION_BUILD_MEMORY_SANITIZER) # TODO: Not implemented (https://go.googlesource.com/go/+/go1.7/misc/cgo/testsanitizers/test.bash) return() endif() diff --git a/source/ports/go_port/source/go_port.go b/source/ports/go_port/source/go_port.go index dca5e08e9..b2de8ed02 100644 --- a/source/ports/go_port/source/go_port.go +++ b/source/ports/go_port/source/go_port.go @@ -27,7 +27,7 @@ package metacall #include // TODO: Sanitizer -// #if defined(__ADDRESS_SANITIZER__) || defined(__THREAD_SANITIZER__) || defined(__MEMORY_SANITIZER__) || defined(__UB_SANITIZER__) +// #if defined(__ADDRESS_SANITIZER__) || defined(__THREAD_SANITIZER__) || defined(__MEMORY_SANITIZER__) // void __lsan_do_leak_check(void); // #endif diff --git a/source/ports/js_port/test/main.cpp b/source/ports/js_port/test/main.cpp index 98fd73946..5d40bb632 100644 --- a/source/ports/js_port/test/main.cpp +++ b/source/ports/js_port/test/main.cpp @@ -320,7 +320,7 @@ void ModulesClear() it != modules.end(); ++it) { /* Disable dlclose when running with address sanitizer in order to maintain stacktraces */ -#if !defined(__ADDRESS_SANITIZER__) && !defined(__THREAD_SANITIZER__) && !defined(__MEMORY_SANITIZER__) && !defined(__UB_SANITIZER__) +#if !defined(__ADDRESS_SANITIZER__) && !defined(__THREAD_SANITIZER__) && !defined(__MEMORY_SANITIZER__) #if defined(JS_PORT_TEST_WIN) FreeLibrary(it->second); #elif defined(JS_PORT_TEST_UNIX) diff --git a/source/ports/rb_port/CMakeLists.txt b/source/ports/rb_port/CMakeLists.txt index 1efafc819..cc3aa171f 100644 --- a/source/ports/rb_port/CMakeLists.txt +++ b/source/ports/rb_port/CMakeLists.txt @@ -35,7 +35,7 @@ set(export_macro "${target_upper}_API") set(interface_path "${CMAKE_CURRENT_SOURCE_DIR}/interface/${target}") set(include_path "${CMAKE_CURRENT_SOURCE_DIR}/include/${target}") -set(source_path "${CMAKE_CURRENT_SOURCE_DIR}/source") +set(source_path "${CMAKE_CURRENT_SOURCE_DIR}/source") set(interfaces ${interface_path}/rb_port.i @@ -102,6 +102,7 @@ else() swig_add_library(${target} LANGUAGE ruby SOURCES ${interfaces} ${headers} ${sources} + OUTPUT_DIR "${PROJECT_OUTPUT_DIR}" ) endif() @@ -133,6 +134,9 @@ set_target_properties(${SWIG_MODULE_${target}_REAL_NAME} PROPERTIES ${DEFAULT_PROJECT_OPTIONS} FOLDER "${IDE_FOLDER}" + + # Set Ruby extension properies + SUFFIX ".so" ) # @@ -182,6 +186,7 @@ target_compile_definitions(${SWIG_MODULE_${target}_REAL_NAME} PUBLIC $<$>:${target_upper}_STATIC_DEFINE> ${DEFAULT_COMPILE_DEFINITIONS} + $<$:RB_PORT_USINGSWIG_EXPORTS> INTERFACE ) diff --git a/source/ports/rb_port/include/rb_port/rb_port.h b/source/ports/rb_port/include/rb_port/rb_port.h index 3788a1b79..69d7b3d4d 100644 --- a/source/ports/rb_port/include/rb_port/rb_port.h +++ b/source/ports/rb_port/include/rb_port/rb_port.h @@ -21,6 +21,9 @@ #ifndef METACALL_SWIG_WRAPPER_RB_PORT_H #define METACALL_SWIG_WRAPPER_RB_PORT_H 1 +/* TODO: Review https://github.com/SketchUp/testup-2/blob/e32a68c5c02e2cbc3a924f40d4987faa05dbcc89/ruby-c-extension/sketchup-taskbarlist/TaskbarProgress/src/RubyUtils/RubyLib.h */ +/* TODO: Unify rb_port with rb_loader */ + /* ... */ #endif /* METACALL_SWIG_WRAPPER_RB_PORT_H */ diff --git a/source/ports/rs_port/CMakeLists.txt b/source/ports/rs_port/CMakeLists.txt index e78c211fc..b64f86fb3 100644 --- a/source/ports/rs_port/CMakeLists.txt +++ b/source/ports/rs_port/CMakeLists.txt @@ -24,7 +24,7 @@ set(target rs_port) message(STATUS "Port ${target}") # Find bindgen (disable when using sanitizers) -if(NOT (OPTION_BUILD_ADDRESS_SANITIZER OR OPTION_BUILD_THREAD_SANITIZER OR OPTION_BUILD_MEMORY_SANITIZER OR OPTION_BUILD_UB_SANITIZER)) +if(NOT (OPTION_BUILD_ADDRESS_SANITIZER OR OPTION_BUILD_THREAD_SANITIZER OR OPTION_BUILD_MEMORY_SANITIZER)) find_program(Rust_BINDGEN_EXECUTABLE bindgen HINTS ${Rust_CARGO_HOME} PATH_SUFFIXES "bin" diff --git a/source/tests/CMakeLists.txt b/source/tests/CMakeLists.txt index 18060e7e1..5d56a5a38 100644 --- a/source/tests/CMakeLists.txt +++ b/source/tests/CMakeLists.txt @@ -48,11 +48,11 @@ endif() option(OPTION_TEST_MEMORYCHECK "Run tests with memory checker (valgrind)." OFF) -if(OPTION_TEST_MEMORYCHECK AND (OPTION_BUILD_ADDRESS_SANITIZER OR OPTION_BUILD_THREAD_SANITIZER OR OPTION_BUILD_MEMORY_SANITIZER OR OPTION_BUILD_UB_SANITIZER)) +if(OPTION_TEST_MEMORYCHECK AND (OPTION_BUILD_ADDRESS_SANITIZER OR OPTION_BUILD_THREAD_SANITIZER OR OPTION_BUILD_MEMORY_SANITIZER)) message(WARNING "OPTION_TEST_MEMORYCHECK and OPTION_BUILD_ADDRESS_SANITIZER are not compatible, disabling memcheck tests.") endif() -if(OPTION_TEST_MEMORYCHECK AND NOT (OPTION_BUILD_ADDRESS_SANITIZER OR OPTION_BUILD_THREAD_SANITIZER OR OPTION_BUILD_MEMORY_SANITIZER OR OPTION_BUILD_UB_SANITIZER)) +if(OPTION_TEST_MEMORYCHECK AND NOT (OPTION_BUILD_ADDRESS_SANITIZER OR OPTION_BUILD_THREAD_SANITIZER OR OPTION_BUILD_MEMORY_SANITIZER)) set(MEMORYCHECK_COMMAND_OPTIONS "${MEMORYCHECK_COMMAND_OPTIONS} --leak-check=full") set(MEMORYCHECK_COMMAND_OPTIONS "${MEMORYCHECK_COMMAND_OPTIONS} --trace-children=yes") set(MEMORYCHECK_COMMAND_OPTIONS "${MEMORYCHECK_COMMAND_OPTIONS} --show-reachable=yes") diff --git a/source/tests/metacall_test/source/metacall_test.cpp b/source/tests/metacall_test/source/metacall_test.cpp index 691552d00..36a225395 100644 --- a/source/tests/metacall_test/source/metacall_test.cpp +++ b/source/tests/metacall_test/source/metacall_test.cpp @@ -280,7 +280,7 @@ TEST_F(metacall_test, DefaultConstructor) metacall_value_destroy(ret); - #if !defined(__ADDRESS_SANITIZER__) && !defined(__THREAD_SANITIZER__) && !defined(__MEMORY_SANITIZER__) && !defined(__UB_SANITIZER__) + #if !defined(__ADDRESS_SANITIZER__) && !defined(__THREAD_SANITIZER__) && !defined(__MEMORY_SANITIZER__) /* Testing corrupted value input */ struct { diff --git a/source/tests/metacall_wasm_test/CMakeLists.txt b/source/tests/metacall_wasm_test/CMakeLists.txt index c48f89c36..0b967b612 100644 --- a/source/tests/metacall_wasm_test/CMakeLists.txt +++ b/source/tests/metacall_wasm_test/CMakeLists.txt @@ -1,5 +1,5 @@ # Check if this loader is enabled -if(NOT OPTION_BUILD_LOADERS OR NOT OPTION_BUILD_LOADERS_WASM) +if(NOT OPTION_BUILD_LOADERS OR NOT OPTION_BUILD_LOADERS_WASM OR NOT OPTION_BUILD_SCRIPTS OR NOT OPTION_BUILD_SCRIPTS_WASM) return() endif() @@ -97,13 +97,6 @@ target_compile_definitions(${target} ${DEFAULT_COMPILE_DEFINITIONS} ) -if(OPTION_BUILD_SCRIPTS AND OPTION_BUILD_SCRIPTS_WASM) - target_compile_definitions(${target} - PRIVATE - BUILD_SCRIPT_TESTS - ) -endif() - # # Compile options # @@ -146,6 +139,11 @@ set_property(TEST ${target} PROPERTY LABELS ${target} ) +if(WIN32 AND OPTION_BUILD_ADDRESS_SANITIZER) + # TODO: This test segfaults in windows when run with addres sanitizer without any output + return() +endif() + if(OPTION_BUILD_THREAD_SANITIZER) # TODO: This test fails when run with thread sanitizer: # diff --git a/source/tests/metacall_wasm_test/source/metacall_wasm_test.cpp b/source/tests/metacall_wasm_test/source/metacall_wasm_test.cpp index 757f079ed..8407e5af2 100644 --- a/source/tests/metacall_wasm_test/source/metacall_wasm_test.cpp +++ b/source/tests/metacall_wasm_test/source/metacall_wasm_test.cpp @@ -36,26 +36,6 @@ class metacall_wasm_test : public testing::Test } }; -void TestFunction(void *handle, const char *name, const std::vector &expected_param_types, enum metacall_value_id expected_return_type) -{ - void *func = metacall_handle_function(handle, name); - - // GoogleTest does not support `ASSERT_NE(NULL, actual)`. - ASSERT_TRUE(func != NULL); - ASSERT_EQ(expected_param_types.size(), metacall_function_size(func)); - - for (size_t i = 0; i < expected_param_types.size(); i++) - { - enum metacall_value_id param_type; - ASSERT_EQ(0, metacall_function_parameter_type(func, i, ¶m_type)); - ASSERT_EQ(expected_param_types[i], param_type); - } - - enum metacall_value_id return_type; - ASSERT_EQ(0, metacall_function_return_type(func, &return_type)); - ASSERT_EQ(expected_return_type, return_type); -} - TEST_F(metacall_wasm_test, InitializeAndDestroy) { // This is extremely hacky and causes an error when loading the buffer, @@ -65,13 +45,15 @@ TEST_F(metacall_wasm_test, InitializeAndDestroy) const char dummy_buffer[1] = { 0 }; metacall_load_from_memory("wasm", dummy_buffer, 1, NULL); - ASSERT_EQ(0, metacall_is_initialized("wasm")); + ASSERT_EQ((int)0, (int)metacall_is_initialized("wasm")); // `metacall_destroy` does nothing if Metacall is not initialized, so we // can safely call it here even though we also call it during tear-down. - ASSERT_EQ(0, metacall_destroy()); + ASSERT_EQ((int)0, (int)metacall_destroy()); } +/* TODO: Address sanitizer seems to break with WASM loading, we should either review this or instrument properly wasmtime library */ +#if !defined(__ADDRESS_SANITIZER__) TEST_F(metacall_wasm_test, LoadBinaryFromMemory) { // See https://webassembly.github.io/spec/core/binary/modules.html#binary-module @@ -79,36 +61,53 @@ TEST_F(metacall_wasm_test, LoadBinaryFromMemory) 0x00, 0x61, 0x73, 0x6d, // Magic bytes 0x01, 0x00, 0x00, 0x00 // Version }; - ASSERT_EQ(0, metacall_load_from_memory("wasm", empty_module, sizeof(empty_module), NULL)); + ASSERT_EQ((int)0, (int)metacall_load_from_memory("wasm", empty_module, sizeof(empty_module), NULL)); const char invalid_module[] = { 0 }; - ASSERT_NE(0, metacall_load_from_memory("wasm", invalid_module, sizeof(invalid_module), NULL)); + ASSERT_NE((int)0, (int)metacall_load_from_memory("wasm", invalid_module, sizeof(invalid_module), NULL)); } TEST_F(metacall_wasm_test, LoadTextFromMemory) { const char *empty_module = "(module)"; - ASSERT_EQ(0, metacall_load_from_memory("wasm", empty_module, strlen(empty_module), NULL)); + ASSERT_EQ((int)0, (int)metacall_load_from_memory("wasm", empty_module, strlen(empty_module), NULL)); const char *invalid_module = "(invalid)"; - ASSERT_NE(0, metacall_load_from_memory("wasm", invalid_module, strlen(invalid_module), NULL)); + ASSERT_NE((int)0, (int)metacall_load_from_memory("wasm", invalid_module, strlen(invalid_module), NULL)); } -/* TODO: Address sanitizer seems to break with WASM loading, we should either review this or instrument properly wasmtime library */ -#if defined(BUILD_SCRIPT_TESTS) && !defined(__ADDRESS_SANITIZER__) TEST_F(metacall_wasm_test, LoadFromFile) { const char *empty_module_filename = "empty_module.wat"; const char *invalid_module_filename = "invalid_module.wat"; - ASSERT_EQ(0, metacall_load_from_file("wasm", &empty_module_filename, 1, NULL)); - ASSERT_NE(0, metacall_load_from_file("wasm", &invalid_module_filename, 1, NULL)); + ASSERT_EQ((int)0, (int)metacall_load_from_file("wasm", &empty_module_filename, 1, NULL)); + ASSERT_NE((int)0, (int)metacall_load_from_file("wasm", &invalid_module_filename, 1, NULL)); } TEST_F(metacall_wasm_test, LoadFromPackage) { - ASSERT_EQ(0, metacall_load_from_package("wasm", "empty_module.wasm", NULL)); - ASSERT_NE(0, metacall_load_from_package("wasm", "invalid_module.wasm", NULL)); + ASSERT_EQ((int)0, (int)metacall_load_from_package("wasm", "empty_module.wasm", NULL)); + ASSERT_NE((int)0, (int)metacall_load_from_package("wasm", "invalid_module.wasm", NULL)); +} + +void TestFunction(void *handle, const char *name, const std::vector &expected_param_types, enum metacall_value_id expected_return_type) +{ + void *func = metacall_handle_function(handle, name); + + ASSERT_NE((void *)NULL, (void *)func); + ASSERT_EQ((size_t)expected_param_types.size(), (size_t)metacall_function_size(func)); + + for (size_t i = 0; i < expected_param_types.size(); ++i) + { + enum metacall_value_id param_type; + ASSERT_EQ((int)0, (int)metacall_function_parameter_type(func, i, ¶m_type)); + ASSERT_EQ((enum metacall_value_id)expected_param_types[i], (enum metacall_value_id)param_type); + } + + enum metacall_value_id return_type; + ASSERT_EQ((int)0, (int)metacall_function_return_type(func, &return_type)); + ASSERT_EQ((enum metacall_value_id)expected_return_type, (enum metacall_value_id)return_type); } TEST_F(metacall_wasm_test, DiscoverFunctions) @@ -116,9 +115,9 @@ TEST_F(metacall_wasm_test, DiscoverFunctions) const char *functions_module_filename = "functions.wat"; void *handle = NULL; - ASSERT_EQ(0, metacall_load_from_file("wasm", &functions_module_filename, 1, &handle)); + ASSERT_EQ((int)0, (int)metacall_load_from_file("wasm", &functions_module_filename, 1, &handle)); - ASSERT_EQ(NULL, metacall_handle_function(handle, "does_not_exist")); + ASSERT_EQ((void *)NULL, (void *)metacall_handle_function(handle, "does_not_exist")); TestFunction(handle, "none_ret_none", {}, METACALL_INVALID); TestFunction(handle, "i64_ret_none", { METACALL_LONG }, METACALL_INVALID); @@ -133,7 +132,7 @@ TEST_F(metacall_wasm_test, CallFunctions) { const char *functions_module_filename = "functions.wat"; - ASSERT_EQ(0, metacall_load_from_file("wasm", &functions_module_filename, 1, NULL)); + ASSERT_EQ((int)0, (int)metacall_load_from_file("wasm", &functions_module_filename, 1, NULL)); void *ret = metacall("none_ret_none"); ASSERT_NE((void *)NULL, (void *)ret); @@ -151,36 +150,36 @@ TEST_F(metacall_wasm_test, CallFunctions) metacall_value_destroy(ret); ret = metacall("none_ret_i32"); - ASSERT_EQ(METACALL_INT, metacall_value_id(ret)); - ASSERT_EQ(1, metacall_value_to_int(ret)); + ASSERT_EQ((enum metacall_value_id)METACALL_INT, (enum metacall_value_id)metacall_value_id(ret)); + ASSERT_EQ((int)1, (int)metacall_value_to_int(ret)); metacall_value_destroy(ret); ret = metacall("none_ret_i32_f32_i64_f64"); - ASSERT_EQ(METACALL_ARRAY, metacall_value_id(ret)); + ASSERT_EQ((enum metacall_value_id)METACALL_ARRAY, (enum metacall_value_id)metacall_value_id(ret)); void **values = metacall_value_to_array(ret); - ASSERT_EQ(METACALL_INT, metacall_value_id(values[0])); - ASSERT_EQ(METACALL_FLOAT, metacall_value_id(values[1])); - ASSERT_EQ(METACALL_LONG, metacall_value_id(values[2])); - ASSERT_EQ(METACALL_DOUBLE, metacall_value_id(values[3])); - ASSERT_EQ(1, metacall_value_to_int(values[0])); - ASSERT_EQ(2, metacall_value_to_float(values[1])); - ASSERT_EQ(3, metacall_value_to_long(values[2])); - ASSERT_EQ(4, metacall_value_to_double(values[3])); + ASSERT_EQ((enum metacall_value_id)METACALL_INT, (enum metacall_value_id)metacall_value_id(values[0])); + ASSERT_EQ((enum metacall_value_id)METACALL_FLOAT, (enum metacall_value_id)metacall_value_id(values[1])); + ASSERT_EQ((enum metacall_value_id)METACALL_LONG, (enum metacall_value_id)metacall_value_id(values[2])); + ASSERT_EQ((enum metacall_value_id)METACALL_DOUBLE, (enum metacall_value_id)metacall_value_id(values[3])); + ASSERT_EQ((int)1, (int)metacall_value_to_int(values[0])); + ASSERT_EQ((float)2.0f, (float)metacall_value_to_float(values[1])); + ASSERT_EQ((long)3, (long)metacall_value_to_long(values[2])); + ASSERT_EQ((double)4.0, (double)metacall_value_to_double(values[3])); metacall_value_destroy(ret); ret = metacall("i32_f32_i64_f64_ret_i32_f32_i64_f64", 0, 0, 0, 0); - ASSERT_EQ(METACALL_ARRAY, metacall_value_id(ret)); + ASSERT_EQ((enum metacall_value_id)METACALL_ARRAY, (enum metacall_value_id)metacall_value_id(ret)); values = metacall_value_to_array(ret); - ASSERT_EQ(METACALL_INT, metacall_value_id(values[0])); - ASSERT_EQ(METACALL_FLOAT, metacall_value_id(values[1])); - ASSERT_EQ(METACALL_LONG, metacall_value_id(values[2])); - ASSERT_EQ(METACALL_DOUBLE, metacall_value_id(values[3])); - ASSERT_EQ(1, metacall_value_to_int(values[0])); - ASSERT_EQ(2, metacall_value_to_float(values[1])); - ASSERT_EQ(3, metacall_value_to_long(values[2])); - ASSERT_EQ(4, metacall_value_to_double(values[3])); + ASSERT_EQ((enum metacall_value_id)METACALL_INT, (enum metacall_value_id)metacall_value_id(values[0])); + ASSERT_EQ((enum metacall_value_id)METACALL_FLOAT, (enum metacall_value_id)metacall_value_id(values[1])); + ASSERT_EQ((enum metacall_value_id)METACALL_LONG, (enum metacall_value_id)metacall_value_id(values[2])); + ASSERT_EQ((enum metacall_value_id)METACALL_DOUBLE, (enum metacall_value_id)metacall_value_id(values[3])); + ASSERT_EQ((int)1, (int)metacall_value_to_int(values[0])); + ASSERT_EQ((float)2.0f, (float)metacall_value_to_float(values[1])); + ASSERT_EQ((long)3, (long)metacall_value_to_long(values[2])); + ASSERT_EQ((double)4.0, (double)metacall_value_to_double(values[3])); metacall_value_destroy(ret); // It should exit with illegal instruction @@ -198,16 +197,16 @@ TEST_F(metacall_wasm_test, LinkModules) "imports.wat" }; - ASSERT_EQ(0, metacall_load_from_file("wasm", modules, sizeof(modules) / sizeof(modules[0]), NULL)); + ASSERT_EQ((int)0, (int)metacall_load_from_file("wasm", modules, sizeof(modules) / sizeof(modules[0]), NULL)); void *ret = metacall("duplicate_func_i32"); - ASSERT_EQ(METACALL_INT, metacall_value_id(ret)); - ASSERT_EQ(1, metacall_value_to_int(ret)); + ASSERT_EQ((enum metacall_value_id)METACALL_INT, (enum metacall_value_id)metacall_value_id(ret)); + ASSERT_EQ((int)1, (int)metacall_value_to_int(ret)); metacall_value_destroy(ret); ret = metacall("duplicate_func_i64"); - ASSERT_EQ(METACALL_LONG, metacall_value_id(ret)); - ASSERT_EQ(2, metacall_value_to_long(ret)); + ASSERT_EQ((enum metacall_value_id)METACALL_LONG, (enum metacall_value_id)metacall_value_id(ret)); + ASSERT_EQ((long)2, (long)metacall_value_to_long(ret)); metacall_value_destroy(ret); } @@ -218,6 +217,6 @@ TEST_F(metacall_wasm_test, InvalidLinkModules) "imports.wat" }; - ASSERT_EQ(1, metacall_load_from_file("wasm", modules, sizeof(modules) / sizeof(modules[0]), NULL)); + ASSERT_EQ((int)1, (int)metacall_load_from_file("wasm", modules, sizeof(modules) / sizeof(modules[0]), NULL)); } #endif diff --git a/tools/metacall-configure.ps1 b/tools/metacall-configure.ps1 index bf0583552..958cee260 100755 --- a/tools/metacall-configure.ps1 +++ b/tools/metacall-configure.ps1 @@ -25,7 +25,6 @@ $Global:BUILD_COVERAGE = 0 $Global:BUILD_ADDRESS_SANITIZER = 0 $Global:BUILD_THREAD_SANITIZER = 0 $Global:BUILD_MEMORY_SANITIZER = 0 -$Global:BUILD_UB_SANITIZER = 0 $Global:PROGNAME = $(Get-Item $PSCommandPath).Basename $Global:Arguments = $args @@ -141,10 +140,6 @@ function sub-options { echo "Build with memory sanitizers" $Global:BUILD_MEMORY_SANITIZER = 1 } - if ( "$option" -eq 'ub-sanitizer' ) { - echo "Build with undefined behavior sanitizers" - $Global:BUILD_UB_SANITIZER = 1 - } } } @@ -393,13 +388,6 @@ function sub-configure { $Global:BUILD_STRING = "$BUILD_STRING -DOPTION_BUILD_MEMORY_SANITIZER=Off" } - # Undefined Behavior Sanitizer - if ( $BUILD_UB_SANITIZER -eq 1 ) { - $Global:BUILD_STRING = "$BUILD_STRING -DOPTION_BUILD_UB_SANITIZER=On" - } else { - $Global:BUILD_STRING = "$BUILD_STRING -DOPTION_BUILD_UB_SANITIZER=Off" - } - # Build type $Global:BUILD_STRING = "$BUILD_STRING -DCMAKE_BUILD_TYPE=$BUILD_TYPE" @@ -447,7 +435,6 @@ function sub-help { echo " address-sanitizer: build with address sanitizer" echo " thread-sanitizer: build with thread sanitizer" echo " memory-sanitizer: build with memory sanitizer" - echo " ub-sanitizer: build with undefined behavior sanitizer" echo "" } diff --git a/tools/metacall-configure.sh b/tools/metacall-configure.sh index 79f7b16a4..8236de49d 100755 --- a/tools/metacall-configure.sh +++ b/tools/metacall-configure.sh @@ -49,7 +49,6 @@ BUILD_COVERAGE=0 BUILD_ADDRESS_SANITIZER=0 BUILD_THREAD_SANITIZER=0 BUILD_MEMORY_SANITIZER=0 -BUILD_UB_SANITIZER=0 # Linux Distro detection if [ -f /etc/os-release ]; then # Either Debian or Ubuntu @@ -179,10 +178,6 @@ sub_options() { echo "Build with memory sanitizer" BUILD_MEMORY_SANITIZER=1 fi - if [ "$option" = 'ub-sanitizer' ]; then - echo "Build with undefined behavior sanitizer" - BUILD_UB_SANITIZER=1 - fi done } @@ -475,13 +470,6 @@ sub_configure() { BUILD_STRING="$BUILD_STRING -DOPTION_BUILD_MEMORY_SANITIZER=Off" fi - # Undefined Behavior Sanitizer - if [ $BUILD_UB_SANITIZER = 1 ]; then - BUILD_STRING="$BUILD_STRING -DOPTION_BUILD_UB_SANITIZER=On" - else - BUILD_STRING="$BUILD_STRING -DOPTION_BUILD_UB_SANITIZER=Off" - fi - # Split cmake config file line by line and add each line to the build string CMAKE_CONFIG_FILE="$ROOT_DIR/CMakeConfig.txt" if [ -f $CMAKE_CONFIG_FILE ]; then @@ -530,7 +518,6 @@ sub_help() { echo " address-sanitizer: build with address sanitizer" echo " thread-sanitizer: build with thread sanitizer" echo " memory-sanitizer: build with memory sanitizer" - echo " ub-sanitizer: build with undefined behavior sanitizer" echo "" } diff --git a/tools/metacall-sanitizer.sh b/tools/metacall-sanitizer.sh index c456e3fbf..541bbf658 100755 --- a/tools/metacall-sanitizer.sh +++ b/tools/metacall-sanitizer.sh @@ -29,8 +29,8 @@ SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &> /dev/null && pwd) ROOT_DIR=$(dirname "$SCRIPT_DIR") BUILD_DIR="${ROOT_DIR}/build" -if [ "${BUILD_SANITIZER}" != "address-sanitizer" ] && [ "${BUILD_SANITIZER}" != "thread-sanitizer" ] && [ "${BUILD_SANITIZER}" != "memory-sanitizer" ] && [ "${BUILD_SANITIZER}" != "ub-sanitizer" ]; then - echo "Sanitizer '${BUILD_SANITIZER}' not supported, use 'address-sanitizer' or 'thread-sanitizer' or 'memory-sanitizer' or 'ub-sanitizer'." +if [ "${BUILD_SANITIZER}" != "address-sanitizer" ] && [ "${BUILD_SANITIZER}" != "thread-sanitizer" ] && [ "${BUILD_SANITIZER}" != "memory-sanitizer" ]; then + echo "Sanitizer '${BUILD_SANITIZER}' not supported, use 'address-sanitizer' or 'thread-sanitizer' or 'memory-sanitizer'." exit 1 fi