diff --git a/.github/workflows/built_test.yml b/.github/workflows/built_test.yml new file mode 100644 index 00000000..dc6a159d --- /dev/null +++ b/.github/workflows/built_test.yml @@ -0,0 +1,156 @@ +# Documentation: https://wiki.unvanquished.net/wiki/Continuous_integration + +name: Build + +on: + push: + branches: + - master + - 'for-*.*.*/sync' # Next-release branch + pull_request: + branches: + - '**' + paths: + - '.github/workflows/build_test.yml' + - '.gitmodules' + # 'android/**' + - 'autotools/**' + - 'compat/**' + - configure.ac + - DEPS + - fetch-externals + - 'm4/**' + - Makefile.am + - 'src/**' + - 'test/**' + - 'wine/**' + +jobs: + build: + name: ${{ matrix.name }} + runs-on: ${{ matrix.vm_image }} + + strategy: + fail-fast: false + matrix: + include: + - name: Linux amd64 GCC + vm_image: ubuntu-22.04 + apt_packages: g++-12 libcurl4-openssl-dev + env_commands: export CC=gcc-12 CXX=g++-12 + - name: Linux i686 GCC + # This platform reliably caught in CI the random thread-related + # bug src/client/linux/linux_client_unittest, making it possible + # to track down and debug it. It also catches more pointer type + # mismatches, thanks to the different sizes. In the end it helps + # improving robustness. + vm_image: ubuntu-22.04 + apt_architecture: i386 + apt_packages: g++-i686-linux-gnu libcurl4-openssl-dev:i386 zlib1g-dev:i386 + env_commands: export CC=i686-linux-gnu-gcc CXX=i686-linux-gnu-g++ + - name: Linux arm64 GCC + vm_image: ubuntu-22.04-arm + apt_packages: g++-12 libcurl4-openssl-dev binutils-x86-64-linux-gnu + env_commands: export CC=gcc-12 CXX=g++-12 + - name: Linux amd64 Clang + vm_image: ubuntu-22.04 + apt_packages: clang libcurl4-openssl-dev + env_commands: export CC=clang CXX=clang++ + - name: Windows amd64 MinGW + vm_image: ubuntu-26.04 + apt_packages: g++-mingw-w64-x86-64 mingw-w64-x86-64-dev gcc-mingw-w64-x86-64-posix-runtime wine libcurl4-openssl-dev libz-mingw-w64-dev + setup_commands: sudo update-alternatives --set x86_64-w64-mingw32-g++ /usr/bin/x86_64-w64-mingw32-g++-posix + env_commands: export TESTDRIVER_SHARED_TEMP_WINEPREFIX=true + configure_options: --host=x86_64-w64-mingw32 --enable-static-mingw + - name: Windows arm64 MinGW + vm_image: windows-11-arm + shell: msys2 {0} + msystem: CLANGARM64 + pacman_packages: base-devel mingw-w64-clang-aarch64-clang mingw-w64-clang-aarch64-gcc-compat autoconf automake libtool + env_commands: export CC=aarch64-w64-mingw32-gcc CXX=aarch64-w64-mingw32-g++ + configure_options: --host=aarch64-w64-mingw32 --enable-static-mingw + - name: macOS amd64 AppleClang + vm_image: macos-15-intel + brew_packages: autoconf automake libtool + nproc_command: sysctl -n hw.logicalcpu + - name: macOS arm64 AppleClang + vm_image: macos-15 + brew_packages: autoconf automake libtool + nproc_command: sysctl -n hw.logicalcpu + + env: + APT_ARCHITECTURE: ${{ matrix.apt_architecture }} + APT_PACKAGES: ${{ matrix.apt_packages }} + BREW_PACKAGES: ${{ matrix.brew_packages }} + SETUP_COMMANDS: ${{ matrix.setup_commands }} + ENV_COMMANDS: ${{ matrix.env_commands }} + NPROC_COMMAND: ${{ matrix.nproc_command }} + CONFIGURE_OPTIONS: ${{ matrix.configure_options }} + + defaults: + run: + shell: ${{ matrix.shell || 'bash' }} + + steps: + - uses: actions/checkout@v5 + + - name: Checkout dependencies + # This doesn't require the MSYS2 shell, so we can run this before the MSYS2 setup, + # and we don't have to install fetch-externals' dependencies in MSYS2 environment + # like python and git which are already provided in the default Git bash environment. + shell: bash + run: | + # To fetch googletest. + ./fetch-externals + + - name: Setup MSYS2 packages + if: ${{ matrix.pacman_packages != '' }} + uses: msys2/setup-msys2@v2 + with: + msystem: ${{ matrix.msystem }} + install: ${{ matrix.pacman_packages }} + update: true + + - name: Setup Apt architecture + if: ${{ matrix.apt_architecture != '' }} + run: | + set -xue + sudo dpkg --add-architecture "${APT_ARCHITECTURE}" + + - name: Setup Apt packages + if: ${{ matrix.apt_packages != '' }} + run: | + set -xue + sudo apt-get update && sudo apt-get -y -q --no-install-recommends install ${APT_PACKAGES} + + - name: Setup Brew packages + if: ${{ matrix.brew_packages != '' }} + run: | + set -xue + brew update && brew install ${BREW_PACKAGES} + + - name: Setup commands + if: ${{ matrix.setup_commands != '' }} + run: | + set -xue + ${SETUP_COMMANDS} + + - name: Build + run: | + set -xue + ${ENV_COMMANDS} + parallelism="$(${NPROC_COMMAND:-nproc})" + echo "Build parallelism: ${parallelism}" + autoreconf -fvi + ./configure ${CONFIGURE_OPTIONS} + make "-j${parallelism}" + + - name: Test + run: | + set -xue + ${ENV_COMMANDS} + parallelism="$(${NPROC_COMMAND:-nproc})" + if ! make "-j${parallelism}" check; then + [ ! -f test-suite.log ] || cat test-suite.log + false + fi diff --git a/DEPS b/DEPS index aa2601e7..da3a7b9c 100644 --- a/DEPS +++ b/DEPS @@ -45,7 +45,7 @@ deps = { "@6910c9d9165801d8827d628cb72eb7ea9dd538c5", # Linux syscall support. - "src/src/third_party/lss": - "https://chromium.googlesource.com/linux-syscall-support/" + - "@29164a80da4d41134950d76d55199ea33fbb9613", + #"src/src/third_party/lss": + # "https://chromium.googlesource.com/linux-syscall-support/" + + # "@29164a80da4d41134950d76d55199ea33fbb9613", } diff --git a/Makefile.am b/Makefile.am index aaa1701f..5f470335 100644 --- a/Makefile.am +++ b/Makefile.am @@ -258,6 +258,21 @@ check_SCRIPTS = \ src/processor/minidump_stackwalk_test \ src/processor/minidump_stackwalk_machine_readable_test +## dump_syms tests +check_DEPS = \ + src/tools/linux/dump_syms/dump_syms \ + src/tools/windows/dump_syms_dwarf/dump_syms_dwarf + +check_SCRIPTS = \ + src/tools/linux/dump_syms/dump_syms_test \ + src/tools/windows/dump_syms_dwarf/dump_syms_dwarf_test + +check_DEPS += \ + src/tools/mac/dump_syms/dump_syms_mac + +check_SCRIPTS += \ + src/tools/mac/dump_syms/dump_syms_mac_test + endif !DISABLE_PROCESSOR @@ -305,6 +320,12 @@ check_PROGRAMS += \ # src/tools/linux/symupload/minidump_upload \ # src/tools/linux/symupload/sym_upload +bin_PROGRAMS += \ + src/tools/mac/dump_syms/dump_syms_mac + +check_PROGRAMS += \ + src/common/mac/macho_reader_unittest + if LINUX_HOST bin_PROGRAMS += \ @@ -312,9 +333,6 @@ bin_PROGRAMS += \ src/tools/linux/pid2md/pid2md \ src/tools/linux/md2core/minidump-2-core -bin_PROGRAMS += \ - src/tools/mac/dump_syms/dump_syms_mac - if HAVE_MEMFD_CREATE libexec_PROGRAMS += \ src/tools/linux/core_handler/core_handler @@ -323,9 +341,6 @@ endif check_PROGRAMS += \ src/tools/linux/md2core/minidump_2_core_unittest -check_PROGRAMS += \ - src/common/mac/macho_reader_unittest - endif LINUX_HOST endif !DISABLE_TOOLS @@ -781,8 +796,12 @@ src_tools_mac_dump_syms_dump_syms_mac_SOURCES = \ src/common/mac/macho_walker.cc \ src/common/mac/macho_walker.h \ src/tools/mac/dump_syms/dump_syms_tool.cc -src_tools_mac_dump_syms_dump_syms_mac_CXXFLAGS= \ - -I$(top_srcdir)/src/third_party/mac_headers \ +src_tools_mac_dump_syms_dump_syms_mac_CXXFLAGS = +if !MACOS_BUILD +src_tools_mac_dump_syms_dump_syms_mac_CXXFLAGS += \ + -I$(top_srcdir)/src/third_party/mac_headers +endif +src_tools_mac_dump_syms_dump_syms_mac_CXXFLAGS += \ $(RUSTC_DEMANGLE_CFLAGS) \ -DHAVE_MACH_O_NLIST_H src_tools_mac_dump_syms_dump_syms_mac_LDADD= \ @@ -905,8 +924,12 @@ src_common_mac_macho_reader_unittest_SOURCES = \ src/common/mac/macho_walker.cc \ src/common/tests/file_utils.cc src_common_mac_macho_reader_unittest_CPPFLAGS = \ - $(AM_CPPFLAGS) $(TEST_CFLAGS) \ - -I$(top_srcdir)/src/third_party/mac_headers \ + $(AM_CPPFLAGS) $(TEST_CFLAGS) +if !MACOS_BUILD +src_common_mac_macho_reader_unittest_CPPFLAGS += \ + -I$(top_srcdir)/src/third_party/mac_headers +endif +src_common_mac_macho_reader_unittest_CPPFLAGS += \ -DHAVE_MACH_O_NLIST_H \ $(PTHREAD_CFLAGS) src_common_mac_macho_reader_unittest_LDADD = \ diff --git a/configure.ac b/configure.ac index bf2eea14..66f97472 100644 --- a/configure.ac +++ b/configure.ac @@ -142,20 +142,17 @@ esac AM_CONDITIONAL(ANDROID_HOST, test x$ANDROID_HOST = xtrue) case $build_os in + darwin*) + MACOS_BUILD=true + ;; mingw* | msys* | cygwin*) WINDOWS_BUILD=true ;; esac -AM_CONDITIONAL(WINE_HOST, test x$WINDOWS_HOST = xtrue -a x$WINDOWS_BUILD != xtrue) +AM_CONDITIONAL(MACOS_BUILD, test x$MACOS_BUILD = xtrue) -# Some tools (like mac ones) only support x86 currently. -case $host_cpu in - i?86|x86_64) - X86_HOST=true - ;; -esac -AM_CONDITIONAL(X86_HOST, test x$X86_HOST = xtrue) +AM_CONDITIONAL(WINE_HOST, test x$WINDOWS_HOST = xtrue -a x$WINDOWS_BUILD != xtrue) AC_ARG_ENABLE(processor, AS_HELP_STRING([--disable-processor], diff --git a/src/client/linux/minidump_writer/minidump_writer_unittest.cc b/src/client/linux/minidump_writer/minidump_writer_unittest.cc index 449ac189..5f74dc0a 100644 --- a/src/client/linux/minidump_writer/minidump_writer_unittest.cc +++ b/src/client/linux/minidump_writer/minidump_writer_unittest.cc @@ -270,12 +270,44 @@ TEST(MinidumpWriterTest, MinidumpStacksSkippedIfRequested) { // current executable). This thread should not be captured in the minidump. pthread_t thread; pthread_attr_t thread_attributes; - pthread_attr_init(&thread_attributes); - pthread_attr_setdetachstate(&thread_attributes, PTHREAD_CREATE_DETACHED); + if (pthread_attr_init(&thread_attributes) != 0) { + syscall(__NR_exit_group, 1); + } + if (pthread_attr_setdetachstate( + &thread_attributes, PTHREAD_CREATE_DETACHED) != 0) { + pthread_attr_destroy(&thread_attributes); + syscall(__NR_exit_group, 1); + } + + const size_t stack_size = 1024 * 1024; + void* thread_stack = mmap(nullptr, stack_size, + PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, + -1, 0); + if (thread_stack == MAP_FAILED) { + pthread_attr_destroy(&thread_attributes); + syscall(__NR_exit_group, 1); + } + memset(thread_stack, 0, stack_size); + + if (pthread_attr_setstack( + &thread_attributes, thread_stack, stack_size) != 0) { + munmap(thread_stack, stack_size); + pthread_attr_destroy(&thread_attributes); + syscall(__NR_exit_group, 1); + } + sigset_t sigset; sigemptyset(&sigset); - pthread_create(&thread, &thread_attributes, - reinterpret_cast(&sigsuspend), &sigset); + const int create_result = + pthread_create(&thread, &thread_attributes, + reinterpret_cast(&sigsuspend), + &sigset); + pthread_attr_destroy(&thread_attributes); + if (create_result != 0) { + munmap(thread_stack, stack_size); + syscall(__NR_exit_group, 1); + } char b; IGNORE_RET(HANDLE_EINTR(read(fds[0], &b, sizeof(b)))); diff --git a/src/common/mac/byteswap.h b/src/common/mac/byteswap.h index c4c7e617..39a342c3 100644 --- a/src/common/mac/byteswap.h +++ b/src/common/mac/byteswap.h @@ -35,6 +35,8 @@ #ifndef COMMON_MAC_BYTESWAP_H_ #define COMMON_MAC_BYTESWAP_H_ +#include "compat/linux.h" + #ifdef __APPLE__ #include @@ -45,12 +47,19 @@ static inline int16_t ByteSwap(int16_t v) { return OSSwapInt16(v); } static inline int32_t ByteSwap(int32_t v) { return OSSwapInt32(v); } static inline int64_t ByteSwap(int64_t v) { return OSSwapInt64(v); } -#elif defined(__linux__) +#else // For NXByteOrder #include #include +#if defined(__MINGW32__) || defined(__MINGW64__) +#include +#define bswap_16(x) __builtin_bswap16(x) +#define bswap_32(x) __builtin_bswap32(x) +#define bswap_64(x) __builtin_bswap64(x) +#else #include #include_next +#endif static inline uint16_t ByteSwap(uint16_t v) { return bswap_16(v); } static inline uint32_t ByteSwap(uint32_t v) { return bswap_32(v); } diff --git a/src/common/memory_allocator.h b/src/common/memory_allocator.h index 5760b0c7..2d708235 100644 --- a/src/common/memory_allocator.h +++ b/src/common/memory_allocator.h @@ -76,7 +76,8 @@ class PageAllocator { template static T AlignUp(T offset, size_t alignment) { assert(alignment > 0 && ((alignment - 1) & alignment) == 0); - return (offset + (alignment - 1)) & ~(alignment - 1); + const T mask = static_cast(alignment - 1); + return (offset + mask) & ~mask; } // Allocates an array with requested amount of `bytes` and at a location with diff --git a/src/common/stabs_to_module.cc b/src/common/stabs_to_module.cc index 06f867e3..7731bc44 100644 --- a/src/common/stabs_to_module.cc +++ b/src/common/stabs_to_module.cc @@ -44,12 +44,16 @@ #include #include "common/stabs_to_module.h" +#include "common/language.h" namespace google_breakpad { // Demangle using abi call. // Older GCC may not support it. static std::string Demangle(const std::string& mangled) { + if (!Language::IsMangledName(mangled)) + return mangled; + int status = 0; char *demangled = abi::__cxa_demangle( mangled.c_str(), nullptr, nullptr, &status); diff --git a/src/common/stabs_to_module_unittest.cc b/src/common/stabs_to_module_unittest.cc index 3befb51c..11e540ea 100644 --- a/src/common/stabs_to_module_unittest.cc +++ b/src/common/stabs_to_module_unittest.cc @@ -214,9 +214,15 @@ TEST(FunctionNames, Mangled) { Module::Function *function = functions[0]; // This is GCC-specific, but we shouldn't be seeing STABS data anywhere // but Linux. +#ifdef _WIN32 +#define WHITESPACE_REGEX "\\s" +#else +#define WHITESPACE_REGEX "[[:space:]]" +#endif EXPECT_THAT(function->name.str(), ::testing::ContainsRegex( - "std::vector\\s?>::" + "std::vector" WHITESPACE_REGEX "?>::" "push_back\\(unsigned long long const&\\)")); +#undef WHITESPACE_REGEX EXPECT_EQ(0xf2cfda63cef7f46dLL, function->address); EXPECT_LT(0U, function->ranges[0].size); // should have used dummy size EXPECT_EQ(0U, function->parameter_size); diff --git a/src/processor/minidump_processor.cc b/src/processor/minidump_processor.cc index 00a1aa6a..b8c1066e 100644 --- a/src/processor/minidump_processor.cc +++ b/src/processor/minidump_processor.cc @@ -436,7 +436,7 @@ static const MDRawSystemInfo* GetSystemInfo(Minidump* dump, } static uint64_t GetAddressForArchitecture(const MDCPUArchitecture architecture, - size_t raw_address) + uint64_t raw_address) { switch (architecture) { case MD_CPU_ARCHITECTURE_X86: diff --git a/src/tools/linux/dump_syms/dump_syms_test b/src/tools/linux/dump_syms/dump_syms_test new file mode 100755 index 00000000..a7a8bedb --- /dev/null +++ b/src/tools/linux/dump_syms/dump_syms_test @@ -0,0 +1,20 @@ +#!/bin/sh + +set -eu + +list_targets() +{ +cat <<\EOF +freebsd15-amd64-clang17 +linuxdebian12-amd64-gcc12 +linuxdebian12-arm64-gcc12 +linuxdebian12-armhf-gcc12 +linuxdebian12-ppc64el-gcc12 +linuxdebian13-riscv64-gcc14 +nacl-amd64-saigoclang21 +nacl-armhf-saigoclang21 +nacl-i686-saigoclang21 +EOF +} + +tests/dump_syms_test 'src/tools/linux/dump_syms/dump_syms' $(list_targets) diff --git a/src/tools/mac/dump_syms/dump_syms_mac_test b/src/tools/mac/dump_syms/dump_syms_mac_test new file mode 100755 index 00000000..ef3e10bd --- /dev/null +++ b/src/tools/mac/dump_syms/dump_syms_mac_test @@ -0,0 +1,13 @@ +#!/bin/sh + +set -eu + +list_targets() +{ +cat <<\EOF +macos10.12-amd64-appleclang21 +macos11.7-arm64-appleclang21 +EOF +} + +tests/dump_syms_test 'src/tools/mac/dump_syms/dump_syms_mac' $(list_targets) diff --git a/src/tools/windows/dump_syms_dwarf/dump_syms_dwarf_test b/src/tools/windows/dump_syms_dwarf/dump_syms_dwarf_test new file mode 100755 index 00000000..4ef9df86 --- /dev/null +++ b/src/tools/windows/dump_syms_dwarf/dump_syms_dwarf_test @@ -0,0 +1,13 @@ +#!/bin/sh + +set -eu + +list_targets() +{ +cat <<\EOF +windows7-amd64-mingwgcc14.exe +windows7-i686-mingwgcc14.exe +EOF +} + +tests/dump_syms_test 'src/tools/windows/dump_syms_dwarf/dump_syms_dwarf' $(list_targets) diff --git a/tests/HOWTO.md b/tests/HOWTO.md new file mode 100644 index 00000000..8fadb255 --- /dev/null +++ b/tests/HOWTO.md @@ -0,0 +1,38 @@ +## Debian Bookworm + +```bash +CXX='x86_64-linux-gnu-g++' make SUFFIX='linuxdebian12-amd64-gcc12-dynamic' +CXX='i686-w64-mingw32-g++' make SUFFIX='linuxdebian12-i686-gcc12-dynamic' +CXX='aarch64-linux-gnu-g++' make SUFFIX='linuxdebian12-arm64-gcc12-dynamic' +CXX='arm-linux-gnueabihf-g++' make SUFFIX='linuxdebian12-armhf-gcc12-dynamic' +CXX='powerpc64le-linux-gnu-g++' make SUFFIX='linuxdebian12-ppc64el-gcc12-dynamic' +``` + +## Debian Trixie + +```bash +CXX='riscv64-linux-gnu-g++' make SUFFIX='linuxdebian13-riscv64-gcc14-dynamic' +CXX='x86_64-w64-mingw32-g++-posix' CXXFLAGS='-static -static-libstdc++ -static-libgcc -D_WIN32_WINNT=0x0601 -DWINVER=0x0601' make SUFFIX='windows7-amd64-mingwgcc14-static' +CXX='i686-w64-mingw32-g++-posix' CXXFLAGS='-static -static-libstdc++ -static-libgcc -D_WIN32_WINNT=0x0601 -DWINVER=0x0601' make SUFFIX='windows7-i686-mingwgcc14-static' +``` + +# macOS + +```bash +CXX='clang' CXXFLAGS='-target x86_64-apple-darwin -mmacos-version-min=10.12' make SUFFIX='macos10.12-amd64-appleclang21-dynamic' +CXX='clang' CXXFLAGS='-target arm64-apple-darwin -mmacos-version-min=11.7' make SUFFIX='macos11.7-arm64-appleclang21-dynamic' +``` + +## FreeBSD 15 + +```bash +CXX='clang' CXXFLAGS='-target x86_64-unknown-freebsd' gmake SUFFIX='freebsd15-amd64-clang17-dynamic' +``` + +## Saigo + +```bash +CXX='x86_64-nacl-clang++' make SUFFIX='nacl-amd64-saigoclang21-static' +CXX='i686-nacl-clang++' make SUFFIX='nacl-i686-saigoclang21-static' +CXX='arm-nacl-clang++' make SUFFIX='nacl-armhf-saigoclang21-static' +``` diff --git a/tests/Makefile b/tests/Makefile new file mode 100644 index 00000000..1e1e36a6 --- /dev/null +++ b/tests/Makefile @@ -0,0 +1,25 @@ +.DEFAULT_GOAL := all + +CXX ?= g++ +CXXFLAGS += -Wall -Wextra -Werror -O0 -g +LDLIBS ?= -lm + +SUFFIX ?= unknown +BASE_TARGETS := test-math +TARGETS := $(addsuffix _$(SUFFIX),$(BASE_TARGETS)) + +.PHONY: all clean + +%_${SUFFIX}: %.cpp + $(CXX) $(CXXFLAGS) $< -o $@ $(LDLIBS) + rm -rf ${@}.dSYM + +all: $(TARGETS) + +clean: + rm -fv $(TARGETS) + +fullclean: + @for target in $(BASE_TARGETS); do \ + rm -fv "$$target"_*; \ + done diff --git a/tests/dump_syms_test b/tests/dump_syms_test new file mode 100755 index 00000000..0911b804 --- /dev/null +++ b/tests/dump_syms_test @@ -0,0 +1,38 @@ +#!/bin/sh + +dump_syms="${1}${EXE_EXT:-}"; shift + +printf 'Print file type for: %s\n' "${dump_syms}" +file "${dump_syms}" + +success='true' + +while [ -n "${1:-}" ] +do + target="${1}"; shift + + for source in test-math + do + sample="tests/${source}_${target}" + + if [ -f "${sample}" ] + then + printf 'Let %s symbolize %s:' "${dump_syms}" "${sample}" + + error_log="$(mktemp)" + + if ${EXE_LAUNCHER:-} "${dump_syms}" "${sample}" >/dev/null 2>"${error_log}" + then + printf ' OK\n' + else + printf ' FAILED\n' + cat "${error_log}" + success='false' + fi + + rm "${error_log}" + fi + done +done + +"${success}" diff --git a/tests/test-math.cpp b/tests/test-math.cpp new file mode 100644 index 00000000..e8674f77 --- /dev/null +++ b/tests/test-math.cpp @@ -0,0 +1,54 @@ + +#include +#include + +double calculate_identity(double x) +{ + return std::sin(x) * std::sin(x) + std::cos(x) * std::cos(x); +} + +double calculate_distance(double x1, double y1, double x2, double y2) +{ + double dx = x2 - x1; + double dy = y2 - y1; + + return std::sqrt(dx * dx + dy * dy); +} + +void print_result(const char* name, double result) +{ + printf("%-30s = %.6f\n", name, result); +} + +int main() +{ + double a = 12.5; + double b = 4.0; + + printf("=== Arithmetic ===\n\n"); + + print_result("Addition", a + b); + print_result("Subtraction", a - b); + print_result("Multiplication", a * b); + print_result("Division", a / b); + + printf("\n=== Math Functions ===\n\n"); + + print_result("Square root", std::sqrt(a)); + print_result("Power", std::pow(b, 3)); + + double angle = 0.75; + + print_result("Sinus", std::sin(angle)); + print_result("Cosinus", std::cos(angle)); + print_result("Pythagorean identity", calculate_identity(angle)); + + printf("\n=== Geometry ===\n\n"); + + print_result( + "Distance", + calculate_distance(1.0, 2.0, 4.0, 6.0) + ); + + return 0; +} diff --git a/tests/test-math_freebsd15-amd64-clang17-dynamic b/tests/test-math_freebsd15-amd64-clang17-dynamic new file mode 100755 index 00000000..5b9a5162 Binary files /dev/null and b/tests/test-math_freebsd15-amd64-clang17-dynamic differ diff --git a/tests/test-math_linuxdebian12-amd64-gcc12-dynamic b/tests/test-math_linuxdebian12-amd64-gcc12-dynamic new file mode 100755 index 00000000..3bbf2a01 Binary files /dev/null and b/tests/test-math_linuxdebian12-amd64-gcc12-dynamic differ diff --git a/tests/test-math_linuxdebian12-arm64-gcc12-dynamic b/tests/test-math_linuxdebian12-arm64-gcc12-dynamic new file mode 100755 index 00000000..ca1e55b6 Binary files /dev/null and b/tests/test-math_linuxdebian12-arm64-gcc12-dynamic differ diff --git a/tests/test-math_linuxdebian12-armhf-gcc12-dynamic b/tests/test-math_linuxdebian12-armhf-gcc12-dynamic new file mode 100755 index 00000000..1f487419 Binary files /dev/null and b/tests/test-math_linuxdebian12-armhf-gcc12-dynamic differ diff --git a/tests/test-math_linuxdebian12-ppc64el-gcc12-dynamic b/tests/test-math_linuxdebian12-ppc64el-gcc12-dynamic new file mode 100755 index 00000000..2d3379e6 Binary files /dev/null and b/tests/test-math_linuxdebian12-ppc64el-gcc12-dynamic differ diff --git a/tests/test-math_linuxdebian13-riscv64-gcc14-dynamic b/tests/test-math_linuxdebian13-riscv64-gcc14-dynamic new file mode 100755 index 00000000..c0debfaf Binary files /dev/null and b/tests/test-math_linuxdebian13-riscv64-gcc14-dynamic differ diff --git a/tests/test-math_macos10.12-amd64-appleclang21-dynamic b/tests/test-math_macos10.12-amd64-appleclang21-dynamic new file mode 100755 index 00000000..3896cbd6 Binary files /dev/null and b/tests/test-math_macos10.12-amd64-appleclang21-dynamic differ diff --git a/tests/test-math_macos11.7-arm64-appleclang21-dynamic b/tests/test-math_macos11.7-arm64-appleclang21-dynamic new file mode 100755 index 00000000..2e967cf2 Binary files /dev/null and b/tests/test-math_macos11.7-arm64-appleclang21-dynamic differ diff --git a/tests/test-math_nacl-amd64-saigoclang21-static b/tests/test-math_nacl-amd64-saigoclang21-static new file mode 100755 index 00000000..e9d444e9 Binary files /dev/null and b/tests/test-math_nacl-amd64-saigoclang21-static differ diff --git a/tests/test-math_nacl-armhf-saigoclang21-static b/tests/test-math_nacl-armhf-saigoclang21-static new file mode 100755 index 00000000..ecdf21ca Binary files /dev/null and b/tests/test-math_nacl-armhf-saigoclang21-static differ diff --git a/tests/test-math_nacl-i686-saigoclang21-static b/tests/test-math_nacl-i686-saigoclang21-static new file mode 100755 index 00000000..972b3bfe Binary files /dev/null and b/tests/test-math_nacl-i686-saigoclang21-static differ diff --git a/tests/test-math_windows7-amd64-mingwgcc14-static.exe b/tests/test-math_windows7-amd64-mingwgcc14-static.exe new file mode 100755 index 00000000..d9659e8f Binary files /dev/null and b/tests/test-math_windows7-amd64-mingwgcc14-static.exe differ diff --git a/tests/test-math_windows7-i686-mingwgcc14-static.exe b/tests/test-math_windows7-i686-mingwgcc14-static.exe new file mode 100755 index 00000000..545b40a4 Binary files /dev/null and b/tests/test-math_windows7-i686-mingwgcc14-static.exe differ