diff --git a/.drone.yml b/.drone.yml index c637bb1..68cefa5 100644 --- a/.drone.yml +++ b/.drone.yml @@ -155,3 +155,4 @@ steps: - rm -rf /light_docs/* - mv ./html/* /light_docs/ + diff --git a/modules/assets/private/shader.cpp b/modules/assets/private/shader.cpp index 53c3b1a..0a568ef 100644 --- a/modules/assets/private/shader.cpp +++ b/modules/assets/private/shader.cpp @@ -2,18 +2,25 @@ namespace lt::assets { +constexpr auto total_metadata_size = // + sizeof(AssetMetadata::type) // + + sizeof(AssetMetadata::version) // + + sizeof(ShaderAsset::Metadata::type) // + + sizeof(BlobMetadata::tag) // + + sizeof(BlobMetadata::offset) // + + sizeof(BlobMetadata::compression_type) // + + sizeof(BlobMetadata::compressed_size) // + + sizeof(BlobMetadata::uncompressed_size); + ShaderAsset::ShaderAsset(const std::filesystem::path &path): m_stream(path) { - constexpr auto total_metadata_size = // - sizeof(AssetMetadata) // - + sizeof(Metadata) // - + sizeof(BlobMetadata); - ensure(m_stream.is_open(), "Failed to open shader asset at: {}", path.string()); + const auto read = [this](auto &field) { + m_stream.read(std::bit_cast(&field), sizeof(field)); + }; m_stream.seekg(0, std::ifstream::end); const auto file_size = static_cast(m_stream.tellg()); - ensure( file_size > total_metadata_size, "Failed to open shader asset at: {}, file smaller than metadata: {} < {}", @@ -22,12 +29,15 @@ ShaderAsset::ShaderAsset(const std::filesystem::path &path): m_stream(path) file_size ); - // NOLINTBEGIN(cppcoreguidelines-pro-type-cstyle-cast) m_stream.seekg(0, std::ifstream::beg); - m_stream.read((char *)&m_asset_metadata, sizeof(m_asset_metadata)); - m_stream.read((char *)&m_metadata, sizeof(m_metadata)); - m_stream.read((char *)&m_code_blob_metadata, sizeof(m_code_blob_metadata)); - // NOLINTEND(cppcoreguidelines-pro-type-cstyle-cast) + read(m_asset_metadata.type); + read(m_asset_metadata.version); + read(m_metadata.type); + read(m_code_blob_metadata.tag); + read(m_code_blob_metadata.offset); + read(m_code_blob_metadata.compression_type); + read(m_code_blob_metadata.compressed_size); + read(m_code_blob_metadata.uncompressed_size); ensure( m_asset_metadata.type == asset_type_identifier, @@ -69,4 +79,70 @@ ShaderAsset::ShaderAsset(const std::filesystem::path &path): m_stream(path) ); } +/* static */ void ShaderAsset::pack( + const std::filesystem::path &destination, + AssetMetadata asset_metadata, + Metadata metadata, + Blob code_blob +) +{ + auto stream = std::ofstream { + destination, + std::ios::binary | std::ios::trunc, + }; + + const auto code_blob_metadata = BlobMetadata { + .tag = std::to_underlying(BlobTag::code), + .offset = total_metadata_size, + .compression_type = CompressionType::none, + .compressed_size = code_blob.size(), + .uncompressed_size = code_blob.size(), + }; + + ensure(stream.is_open(), "Failed to pack shader asset to {}", destination.string()); + const auto write = [&stream](auto &field) { + stream.write(std::bit_cast(&field), sizeof(field)); + }; + write(asset_metadata.type); + write(asset_metadata.version); + write(metadata.type); + write(code_blob_metadata.tag); + write(code_blob_metadata.offset); + write(code_blob_metadata.compression_type); + write(code_blob_metadata.compressed_size); + write(code_blob_metadata.uncompressed_size); + stream.write(std::bit_cast(code_blob.data()), static_cast(code_blob.size())); +} + +void ShaderAsset::unpack_to(BlobTag tag, std::span destination) const +{ + ensure(tag == BlobTag::code, "Invalid blob tag for shader asset: {}", std::to_underlying(tag)); + + ensure( + destination.size() >= m_code_blob_metadata.uncompressed_size, + "Failed to unpack shader blob {} to destination ({}) of size {} since it's smaller " + "than the blobl's uncompressed size: {}", + std::to_underlying(tag), + std::bit_cast(destination.data()), + destination.size(), + m_code_blob_metadata.uncompressed_size + ); + + m_stream.seekg(static_cast(m_code_blob_metadata.offset)); + m_stream.read( + std::bit_cast(destination.data()), + static_cast(m_code_blob_metadata.uncompressed_size) + ); +} + +[[nodiscard]] auto ShaderAsset::unpack(BlobTag tag) const -> Blob +{ + ensure(tag == BlobTag::code, "Invalid blob tag for shader asset: {}", std::to_underlying(tag)); + + auto blob = Blob(m_code_blob_metadata.uncompressed_size); + unpack_to(tag, blob); + + return blob; +} + } // namespace lt::assets diff --git a/modules/assets/private/shader.test.cpp b/modules/assets/private/shader.test.cpp index 357bec8..32ce6cb 100644 --- a/modules/assets/private/shader.test.cpp +++ b/modules/assets/private/shader.test.cpp @@ -40,10 +40,15 @@ Suite packing = "shader_pack"_suite = [] { dummy_blob.emplace_back(static_cast(idx)); } - const auto expected_size = // - sizeof(AssetMetadata) // - + sizeof(ShaderAsset::Metadata) // - + sizeof(BlobMetadata) // + const auto expected_size = // + sizeof(AssetMetadata::type) // + + sizeof(AssetMetadata::version) // + + sizeof(ShaderAsset::Metadata::type) // + + sizeof(BlobMetadata::tag) // + + sizeof(BlobMetadata::offset) // + + sizeof(BlobMetadata::compression_type) // + + sizeof(BlobMetadata::compressed_size) // + + sizeof(BlobMetadata::uncompressed_size) // + dummy_blob.size(); ShaderAsset::pack( diff --git a/modules/assets/public/shader.hpp b/modules/assets/public/shader.hpp index ab68014..c8f6061 100644 --- a/modules/assets/public/shader.hpp +++ b/modules/assets/public/shader.hpp @@ -32,33 +32,14 @@ public: AssetMetadata asset_metadata, Metadata metadata, Blob code_blob - ) - { - auto stream = std::ofstream { - destination, - std::ios::binary | std::ios::trunc, - }; - ensure(stream.is_open(), "Failed to pack shader asset to {}", destination.string()); - - // NOLINTBEGIN(cppcoreguidelines-pro-type-cstyle-cast) - stream.write((char *)&asset_metadata, sizeof(asset_metadata)); - stream.write((char *)&metadata, sizeof(metadata)); - - auto code_blob_metadata = BlobMetadata { - .tag = std::to_underlying(BlobTag::code), - .offset = static_cast(stream.tellp()) + sizeof(BlobMetadata), - .compression_type = CompressionType::none, - .compressed_size = code_blob.size(), - .uncompressed_size = code_blob.size(), - }; - stream.write((char *)&code_blob_metadata, sizeof(BlobMetadata)); - - stream.write((char *)code_blob.data(), static_cast(code_blob.size())); - // NOLINTEND(cppcoreguidelines-pro-type-cstyle-cast) - } + ); ShaderAsset(const std::filesystem::path &path); + void unpack_to(BlobTag tag, std::span destination) const; + + [[nodiscard]] auto unpack(BlobTag tag) const -> Blob; + [[nodiscard]] auto get_asset_metadata() const -> const AssetMetadata & { return m_asset_metadata; @@ -80,45 +61,6 @@ public: return m_code_blob_metadata; } - void unpack_to(BlobTag tag, std::span destination) const - { - ensure( - tag == BlobTag::code, - "Invalid blob tag for shader asset: {}", - std::to_underlying(tag) - ); - - ensure( - destination.size() >= m_code_blob_metadata.uncompressed_size, - "Failed to unpack shader blob {} to destination ({}) of size {} since it's smaller " - "than the blobl's uncompressed size: {}", - std::to_underlying(tag), - (size_t)(destination.data()), // NOLINT(cppcoreguidelines-pro-type-cstyle-cast) - destination.size(), - m_code_blob_metadata.uncompressed_size - ); - - m_stream.seekg(static_cast(m_code_blob_metadata.offset)); - m_stream.read( - (char *)destination.data(), // NOLINT(cppcoreguidelines-pro-type-cstyle-cast) - static_cast(m_code_blob_metadata.uncompressed_size) - ); - } - - [[nodiscard]] auto unpack(BlobTag tag) const -> Blob - { - ensure( - tag == BlobTag::code, - "Invalid blob tag for shader asset: {}", - std::to_underlying(tag) - ); - - auto blob = Blob(m_code_blob_metadata.uncompressed_size); - unpack_to(tag, blob); - - return blob; - } - private: AssetMetadata m_asset_metadata {}; diff --git a/modules/renderer/private/backend/vk/context/instance.cpp b/modules/renderer/private/backend/vk/context/instance.cpp index d4451b3..0f832c1 100644 --- a/modules/renderer/private/backend/vk/context/instance.cpp +++ b/modules/renderer/private/backend/vk/context/instance.cpp @@ -112,7 +112,7 @@ Instance::~Instance() unload_library(); } -void Instance::initialize_instance() +__attribute__((no_sanitize("memory"))) void Instance::initialize_instance() { auto app_info = VkApplicationInfo { .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, @@ -217,6 +217,7 @@ void Instance::initialize_instance() vkc(vk_enumerate_instance_extension_properties(nullptr, &count, nullptr)); auto extensions = std::vector(count); + memset(extensions.data(), 0, extensions.size() * sizeof(VkExtensionProperties)); vkc(vk_enumerate_instance_extension_properties(nullptr, &count, extensions.data())); // log_inf("Available vulkan instance extensions:"); @@ -230,9 +231,9 @@ void Instance::initialize_instance() ensure(m_instance, "Failed to create vulkan instance"); } -void Instance::load_library() +__attribute__((no_sanitize("memory"))) void Instance::load_library() { - constexpr auto runtime_loader_flags = RTLD_NOW | RTLD_DEEPBIND | RTLD_LOCAL | RTLD_NODELETE; + constexpr auto runtime_loader_flags = RTLD_NOW | RTLD_LOCAL | RTLD_NODELETE; library = dlopen("libvulkan.so.1", runtime_loader_flags); if (!library) { @@ -247,7 +248,7 @@ void Instance::load_library() ensure(vk_get_instance_proc_address, "Failed to load vulkan function: vkGetInstanceProcAddr"); } -void Instance::unload_library() +__attribute__((no_sanitize("memory"))) void Instance::unload_library() { if (!library) { @@ -262,7 +263,7 @@ void Instance::unload_library() // library = nullptr; } -void Instance::load_global_functions() +__attribute__((no_sanitize("memory"))) void Instance::load_global_functions() { constexpr auto load_fn = [](T &pfn, const char *fn_name) { // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) @@ -276,7 +277,7 @@ void Instance::load_global_functions() load_fn(vk_enumerate_instance_layer_properties, "vkEnumerateInstanceLayerProperties"); } -void Instance::load_instance_functions() +__attribute__((no_sanitize("memory"))) void Instance::load_instance_functions() { const auto load_fn = [&](T &pfn, const char *fn_name) { // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) @@ -320,7 +321,7 @@ void Instance::load_instance_functions() load_fn(vk_destroy_surface_khr, "vkDestroySurfaceKHR"); } -void Instance::load_device_functions_impl(VkDevice device) +__attribute__((no_sanitize("memory"))) void Instance::load_device_functions_impl(VkDevice device) { const auto load_fn = [&](T &pfn, const char *fn_name) { // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) diff --git a/modules/renderer/private/backend/vk/context/instance.hpp b/modules/renderer/private/backend/vk/context/instance.hpp index a4b337a..0e86da2 100644 --- a/modules/renderer/private/backend/vk/context/instance.hpp +++ b/modules/renderer/private/backend/vk/context/instance.hpp @@ -64,17 +64,17 @@ private: Instance(); - void initialize_instance(); + __attribute__((no_sanitize("memory"))) void initialize_instance(); - void load_library(); + __attribute__((no_sanitize("memory"))) void load_library(); - void unload_library(); + __attribute__((no_sanitize("memory"))) void unload_library(); - void load_global_functions(); + __attribute__((no_sanitize("memory"))) void load_global_functions(); - void load_instance_functions(); + __attribute__((no_sanitize("memory"))) void load_instance_functions(); - void load_device_functions_impl(VkDevice device); + __attribute__((no_sanitize("memory"))) void load_device_functions_impl(VkDevice device); VkInstance m_instance = VK_NULL_HANDLE; diff --git a/modules/surface/private/linux/system.cpp b/modules/surface/private/linux/system.cpp index e1b44b2..b98ec6e 100644 --- a/modules/surface/private/linux/system.cpp +++ b/modules/surface/private/linux/system.cpp @@ -11,14 +11,19 @@ #include #include +// +#include + namespace lt::surface { template -int XEventTypeEquals(Display *, XEvent *event, XPointer winptr) +auto XEventTypeEquals(Display *display, XEvent *event, char *winptr) -> int { + std::ignore = display; return ( event->type == EventType - && *(reinterpret_cast(winptr)) == reinterpret_cast(event)->window + && *(std::bit_cast(winptr)) + == std::bit_cast(event)->window ); } @@ -100,7 +105,10 @@ void System::on_unregister() { } -void System::create_surface_component(ecs::EntityId entity, SurfaceComponent::CreateInfo info) +__attribute__((no_sanitize_memory)) void System::create_surface_component( + ecs::EntityId entity, + SurfaceComponent::CreateInfo info +) try { auto &component = m_registry->add(entity, info); @@ -160,9 +168,14 @@ try XSetWMProtocols(display, main_window, &surface.m_native_data.wm_delete_message, 1); // code to remove decoration - auto hints = std::array { 2, 0, 0, 0, 0 }; + auto hints = std::array { 2, 0, 0, 0, 0 }; const auto motif_hints = XInternAtom(display, "_MOTIF_WM_HINTS", False); +#if defined(__clang__) && __has_feature(memory_sanitizer) + auto bytes = (size_t)(1u) * (size_t)hints.size(); + __msan_unpoison((void *)hints.data(), bytes); +#endif + XChangeProperty( display, surface.m_native_data.window, @@ -331,7 +344,10 @@ void System::modify_title(SurfaceComponent &surface, const ModifyTitleRequest &r XStoreName(display, window, request.title.c_str()); } -void System::modify_resolution(SurfaceComponent &surface, const ModifyResolutionRequest &request) +__attribute__((no_sanitize("memory"))) void System::modify_resolution( + SurfaceComponent &surface, + const ModifyResolutionRequest &request +) { // surface.m_resolution = request.resolution; @@ -340,7 +356,7 @@ void System::modify_resolution(SurfaceComponent &surface, const ModifyResolution // XResizeWindow(display, window, width, height); // get baseline serial number for X requests generated from XResizeWindow - uint64_t serial = NextRequest(display); + auto serial = NextRequest(display); // request a new window size from the X server XResizeWindow(display, window, static_cast(width), static_cast(height)); @@ -396,7 +412,7 @@ void System::modify_position(SurfaceComponent &surface, const ModifyPositionRequ const auto &[x, y] = request.position; // get baseline serial number for X requests generated from XResizeWindow - uint64_t serial = NextRequest(display); + auto serial = NextRequest(display); XMoveWindow(display, window, static_cast(x), static_cast(y)); // flush output queue and wait for X server to processes the request diff --git a/modules/surface/private/system.test.cpp b/modules/surface/private/system.test.cpp index fe9adb4..3ea6643 100644 --- a/modules/surface/private/system.test.cpp +++ b/modules/surface/private/system.test.cpp @@ -16,7 +16,6 @@ using test::expect_eq; using test::expect_ne; using test::expect_not_nullptr; using test::expect_throw; -using test::expect_true; using test::Suite; [[nodiscard]] auto tick_info() -> app::TickInfo diff --git a/modules/surface/public/system.hpp b/modules/surface/public/system.hpp index 24e36e9..6993d49 100644 --- a/modules/surface/public/system.hpp +++ b/modules/surface/public/system.hpp @@ -27,7 +27,10 @@ public: void on_unregister() override; - void create_surface_component(ecs::EntityId entity, SurfaceComponent::CreateInfo info); + __attribute__((no_sanitize("memory"))) void create_surface_component( + ecs::EntityId entity, + SurfaceComponent::CreateInfo info + ); void tick(app::TickInfo tick) override; @@ -45,12 +48,12 @@ private: void modify_title(struct SurfaceComponent &surface, const struct ModifyTitleRequest &request); - void modify_resolution( + __attribute__((no_sanitize("memory"))) void modify_resolution( struct SurfaceComponent &surface, const struct ModifyResolutionRequest &request ); - void modify_position( + __attribute__((no_sanitize("memory"))) void modify_position( struct SurfaceComponent &surface, const struct ModifyPositionRequest &request ); diff --git a/tools/ci/amd64/Dockerfile b/tools/ci/amd64/Dockerfile index e054f7d..1646e8f 100644 --- a/tools/ci/amd64/Dockerfile +++ b/tools/ci/amd64/Dockerfile @@ -1,99 +1,301 @@ FROM archlinux:latest +## Configurations ## +RUN \ +mkdir /msan \ +&& echo 'src:*' > /msan/ignorelist_all_sources \ +&& sed -i 's/^#ParallelDownloads = .*/ParallelDownloads = 8/' /etc/pacman.conf \ +&& echo 'NoExtract = usr/share/{man,doc,info}/*' >> /etc/pacman.conf + ## Packages ## RUN \ -sed -i 's/^#ParallelDownloads = .*/ParallelDownloads = 8/' /etc/pacman.conf \ -&& echo 'NoExtract = usr/share/{man,doc,info}/*' >> /etc/pacman.conf \ -&& pacman -Syyu --noconfirm --needed --disable-download-timeout \ -afl++ \ -afl-utils \ -base-devel \ -bash \ -clang \ -cmake \ -curl \ -expat \ -gcc \ -gdb \ -git \ -glm \ -libc++ \ -libinput \ -libpciaccess \ -libpng \ -libunwind \ -libx11 \ -libxcb \ -libxcursor \ -libxi \ -libxinerama \ -libxpresent \ -libxrandr \ -lz4 \ -mesa \ -mold \ -ninja \ -python \ -python-distlib \ -python-distutils-extra \ -python-jsonschema \ -qt5-base \ -qt6-base \ -valgrind \ -vulkan-headers \ -vulkan-icd-loader \ -vulkan-tools \ -vulkan-validation-layers \ -wayland \ -wayland-protocols \ -wget \ -xcb-util \ -xcb-util-cursor \ -xcb-util-keysyms \ -xcb-util-wm \ -xorg-server-xvfb \ -xorg-util-macros \ -xtrans \ -zlib \ -zstd \ +pacman -Syyu --noconfirm --needed --disable-download-timeout \ + afl++ \ + afl-utils \ + base-devel \ + bash \ + cbindgen \ + clang \ + cmake \ + curl \ + debuginfod \ + directx-headers \ + elfutils \ + expat \ + gcc \ + gcc-libs \ + gdb \ + git \ + glibc \ + glm \ + glslang \ + libc++ \ + libclc \ + libdrm \ + libelf \ + libglvnd \ + libinput \ + libpciaccess \ + libpng \ + libunwind \ + libva \ + libx11 \ + libxcb \ + libxdamage \ + libxext \ + libxfixes \ + libxi \ + libxinerama \ + libxml2 \ + libxpresent \ + libxrandr \ + libxshmfence \ + libxxf86vm \ + lm_sensors \ + llvm \ + lz4 \ + meson \ + mold \ + ninja \ + python \ + python-distlib \ + python-distutils-extra \ + python-jsonschema \ + python-mako \ + python-packaging \ + python-ply \ + python-pyaml \ + qt5-base \ + qt6-base \ + rust \ + rust-bindgen \ + spirv-llvm-translator \ + spirv-tools \ + systemd-libs \ + valgrind \ + vulkan-headers \ + vulkan-icd-loader \ + vulkan-tools \ + vulkan-validation-layers \ + wayland \ + wayland-protocols \ + wget \ + xcb-proto \ + xcb-util \ + xcb-util-cursor \ + xcb-util-keysyms \ + xcb-util-wm \ + xorg-server-xvfb \ + xorg-util-macros \ + xorgproto \ + xtrans \ + zlib \ + zstd \ && pacman -Scc --noconfirm -## Sanitizers ## +## Libc++ ## RUN \ -git clone --depth=1 https://github.com/llvm/llvm-project.git -b llvmorg-20.1.8 \ -&& mkdir llvm-project/build-lsan llvm-project/build-msan \ +git clone \ + --branch llvmorg-20.1.8 \ + --depth=1 \ + https://github.com/llvm/llvm-project.git + +RUN cd llvm-project/ \ \ -&& cd llvm-project/build-lsan \ -&& cmake -G Ninja \ - -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_LINKER_TYPE="MOLD" \ - -DCMAKE_INSTALL_PREFIX=/libcxx_lsan \ - -DCMAKE_C_COMPILER=clang \ - -DCMAKE_CXX_COMPILER=clang++ \ - -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi" \ - -DLLVM_ENABLE_PIC=ON \ - -DLIBCXX_INSTALL_MODULES=ON \ - -DLIBCXXABI_USE_LLVM_UNWINDER=OFF \ - -DLLVM_USE_SANITIZER=Leaks \ - ../runtimes \ -&& ninja cxx cxxabi \ -&& ninja install-cxx install-cxxabi \ +&& cmake \ + -S ./runtimes \ + -B ./build-lsan \ + -G Ninja \ + -D CMAKE_LINKER_TYPE="MOLD" \ + -D CMAKE_BUILD_TYPE=Release \ + -D CMAKE_INSTALL_PREFIX=/libcxx_lsan \ + -D CMAKE_C_COMPILER=$(which clang) \ + -D CMAKE_CXX_COMPILER=$(which clang++) \ + -D LLVM_ENABLE_PROJECTS="clang;compiler-rt" \ + -D LLVM_ENABLE_RUNTIMES="libcxx;libcxxabi" \ + -D LLVM_TARGETS_TO_BUILD="X86;SPIRV" \ + -D LLVM_ENABLE_PIC=ON \ + -D LIBCXX_INSTALL_MODULES=ON \ + -D LIBCXXABI_USE_LLVM_UNWINDER=OFF \ + -D LLVM_USE_SANITIZER=Leaks \ +&& cd ./build-lsan/ && ninja cxx cxxabi && ninja install-cxx install-cxxabi && cd ../ \ \ -&& cd ../build-msan \ -&& cmake -G Ninja \ - -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_LINKER_TYPE="MOLD" \ - -DCMAKE_INSTALL_PREFIX=/libcxx_msan \ - -DCMAKE_C_COMPILER=clang \ - -DCMAKE_CXX_COMPILER=clang++ \ - -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi" \ - -DLLVM_ENABLE_PIC=ON \ - -DLIBCXX_INSTALL_MODULES=ON \ - -DLIBCXXABI_USE_LLVM_UNWINDER=OFF \ - -DLLVM_USE_SANITIZER=MemoryWithOrigins \ - ../runtimes \ -&& ninja cxx cxxabi \ -&& ninja install-cxx install-cxxabi \ -\ -&& cd ../.. \ -&& rm -rf llvm-project +&& cmake \ + -S ./runtimes \ + -B ./build-msan \ + -G Ninja \ + -D CMAKE_LINKER_TYPE="MOLD" \ + -D CMAKE_BUILD_TYPE=Release \ + -D CMAKE_INSTALL_PREFIX=/libcxx_msan \ + -D CMAKE_C_COMPILER=$(which clang) \ + -D CMAKE_CXX_COMPILER=$(which clang++) \ + -D LLVM_ENABLE_PROJECTS="clang;compiler-rt" \ + -D LLVM_ENABLE_RUNTIMES="libcxx;libcxxabi" \ + -D LLVM_TARGETS_TO_BUILD="X86;SPIRV" \ + -D LLVM_ENABLE_PIC=ON \ + -D LIBCXX_INSTALL_MODULES=ON \ + -D LIBCXXABI_USE_LLVM_UNWINDER=OFF \ + -D LLVM_USE_SANITIZER=MemoryWithOrigins \ +&& cd ./build-msan/ && ninja cxx cxxabi && ninja install-cxx install-cxxabi && cd ../ + +## libxcb ## +RUN \ +wget https://x.org/releases/individual/lib/libxcb-1.17.0.tar.xz \ +&& tar xf libxcb-1.17.0.tar.xz \ +&& cd libxcb-1.17.0 \ +&& export CC=clang \ +&& export CFLAGS=" \ + -fsanitize=memory \ + -fsanitize-memory-track-origins \ + -fsanitize-ignorelist=/msan/ignorelist_all_sources \ + -fno-omit-frame-pointer \ + -g \ + -fPIC" \ +&& export LDFLAGS=" \ + -fsanitize=memory \ + -fsanitize-memory-track-origins \ + -fsanitize-ignorelist=/msan/ignorelist_all_sources \ + -fno-omit-frame-pointer \ + -g \ + -fPIC" \ +&& ./configure \ + --prefix=/msan \ + --disable-static \ + --without-doxygen \ +&& make && make install \ +&& cd .. && rm -rf libxcb-1.17.0 libxcb-1.17.0.tar.xz + +## libx11 ## +RUN \ +wget https://x.org/releases/individual/lib/libX11-1.8.12.tar.xz \ +&& tar xf libX11-1.8.12.tar.xz \ +&& cd libX11-1.8.12 \ +&& export CC=clang \ +&& export CFLAGS=" \ +-fsanitize=memory \ +-fsanitize-memory-track-origins \ +-fsanitize-ignorelist=/msan/ignorelist_all_sources \ +-fno-omit-frame-pointer \ +-g \ +-fPIC" \ +&& export LDFLAGS=" \ +-fsanitize=memory \ +-fsanitize-memory-track-origins \ +-fsanitize-ignorelist=/msan/ignorelist_all_sources \ +-fno-omit-frame-pointer \ +-g \ +-fPIC" \ +&& export PKG_CONFIG_PATH=/msan/lib/pkgconfig:$PKG_CONFIG_PATH \ +&& ./configure \ + --prefix=/msan \ + --disable-static \ +&& make && make install \ +&& cd .. && rm -rf libX11-1.8.12 libX11-1.8.12.tar.xz + +RUN wget 'https://sdk.lunarg.com/sdk/download/1.4.328.1/linux/vulkansdk-linux-x86_64-1.4.328.1.tar.xz' +RUN tar xf vulkansdk-linux-x86_64-1.4.328.1.tar.xz + +## Vulkan SDK ## +RUN \ +cd /1.4.328.1 \ +&& chmod +x ./vulkansdk \ +&& chmod +x ./setup-env.sh \ +&& export CC="$(which clang)" \ +&& export CXX="$(which clang++)" \ +&& export CXXFLAGS="\ + -fsanitize=memory \ + -fsanitize-memory-track-origins \ + -fsanitize-ignorelist=/msan/ignorelist_all_sources \ + -fno-omit-frame-pointer \ + -g \ + -std=c++23 \ + -nostdinc++ \ + -isystem /libcxx_msan/include/c++/v1/"\ +&& export CFLAGS="\ + -fsanitize=memory \ + -fsanitize-memory-track-origins \ + -fno-omit-frame-pointer \ + -g" \ +&& export LDFLAGS="\ + -fsanitize=memory \ + -fsanitize-memory-track-origins \ + -fsanitize-ignorelist=/msan/ignorelist_all_sources \ + -g \ + -std=c++23 \ + -L/msan/lib -Wl,-rpath,/msan/lib \ + -L/libcxx_msan/lib -Wl,-rpath,/libcxx_msan/lib \ + -lc++ \ + -lc++abi" \ +&& ./vulkansdk \ + --debug \ + --numjobs `nproc` \ + vulkan-loader + +## Mesa ## +RUN git clone \ + --branch='25.2'\ + --depth=1 \ + https://gitlab.freedesktop.org/mesa/mesa.git + +RUN \ +export CXX=$(which clang++) \ +&& export CC=$(which clang) \ +&& export CXXFLAGS="\ + -fsanitize=memory \ + -fsanitize-memory-track-origins \ + -fno-omit-frame-pointer \ + -g \ + -nostdinc++ \ + -isystem /libcxx_msan/include/c++/v1/"\ +&& export CFLAGS="\ + -fsanitize=memory \ + -fsanitize-memory-track-origins \ + -fno-omit-frame-pointer \ + -g" \ +&& export LDFLAGS="\ + -fsanitize=memory \ + -fsanitize-memory-track-origins \ + -g \ + -L/msan/lib -Wl,-rpath,/msan/lib \ + -L/libcxx_msan/lib -Wl,-rpath,/libcxx_msan/lib \ + -lc++ \ + -lc++abi" \ +&& meson setup ./ _build \ + -D build-tests=false \ + -D enable-glcpp-tests=false \ + -D build-radv-tests=false \ + -D build-aco-tests=false \ + -D install-intel-gpu-tests=false \ + -D gallium-mediafoundation-test=false \ + -D android-libbacktrace=disabled \ + -D split-debug=disabled \ + -D b_ndebug=true \ + -D b_lto=false \ + -D egl=enabled \ + -D gallium-drivers=r300,r600,radeonsi,nouveau,virgl,svga,softpipe,llvmpipe,i915,iris,crocus,zink \ + -D gallium-extra-hud=true \ + -D gallium-rusticl=true \ + -D gallium-va=enabled \ + -D gbm=enabled \ + -D gles1=disabled \ + -D gles2=enabled \ + -D glvnd=enabled \ + -D glx=dri \ + -D libunwind=enabled \ + -D llvm=enabled \ + -D lmsensors=disabled \ + -D microsoft-clc=disabled \ + -D platforms=x11,wayland \ + -D valgrind=disabled \ + -D video-codecs=all \ + -D vulkan-drivers=amd,intel,intel_hasvk,swrast,virtio,nouveau \ + -D vulkan-layers=device-select,intel-nullhw,overlay \ + -D tools='' \ + -D zstd=enabled \ + -D buildtype=plain \ + -D prefix=/usr \ + -D sysconfdir=/etc \ + --wrap-mode=nofallback \ + --force-fallback-for=syn,paste,rustc-hash \ +&& ninja -C _build + diff --git a/tools/ci/amd64/clang/msan.supp b/tools/ci/amd64/clang/msan.supp new file mode 100644 index 0000000..05124f8 --- /dev/null +++ b/tools/ci/amd64/clang/msan.supp @@ -0,0 +1,3 @@ +src:* +obj:* +fun:*