From 1d208febe312c531c25b41e56e9166af85411af3 Mon Sep 17 00:00:00 2001 From: Xinyao Zhang <43081360+zhangxinyao88@users.noreply.github.com> Date: Sat, 24 Oct 2026 16:40:28 -0400 Subject: [PATCH 1/2] [C++] Initialize oversized PageArena allocation metadata Represent a dedicated oversized block as a fully consumed page. Its null cursor previously broke used-byte accounting and triggered UBSan when a later small allocation tried to reuse the block. Cover used-byte totals, successive oversized blocks, retained data and reset. Preserve the existing payload address and alignment. --- cpp/src/common/allocator/page_arena.cc | 7 ++++- cpp/src/common/allocator/page_arena.h | 2 -- cpp/test/common/allocator/page_arena_test.cc | 31 ++++++++++++++++++++ 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/cpp/src/common/allocator/page_arena.cc b/cpp/src/common/allocator/page_arena.cc index 8abfd9d0e..47d8be421 100644 --- a/cpp/src/common/allocator/page_arena.cc +++ b/cpp/src/common/allocator/page_arena.cc @@ -45,7 +45,12 @@ char* PageArena::alloc(uint32_t size) { return new_page->alloc(size); } else { void* ptr = base_allocator_.alloc(size + sizeof(Page), mid_); - Page* new_page = new (ptr) Page(dummy_head_.next_); + if (UNLIKELY(ptr == nullptr)) { + return nullptr; + } + Page* new_page = new (ptr) Page(size, dummy_head_.next_); + // A dedicated oversized page is fully consumed and cannot be reused. + new_page->cur_alloc_ = new_page->page_end_; dummy_head_.next_ = new_page; return reinterpret_cast(new_page) + sizeof(Page); } diff --git a/cpp/src/common/allocator/page_arena.h b/cpp/src/common/allocator/page_arena.h index c0dfbebb9..40aad4c96 100644 --- a/cpp/src/common/allocator/page_arena.h +++ b/cpp/src/common/allocator/page_arena.h @@ -76,8 +76,6 @@ class PageArena { class Page { public: Page() : next_(nullptr), page_end_(nullptr), cur_alloc_(nullptr) {} - explicit Page(Page* next_page) - : next_(next_page), page_end_(nullptr), cur_alloc_(nullptr) {} Page(uint32_t page_size, Page* next_page) { next_ = next_page; cur_alloc_ = diff --git a/cpp/test/common/allocator/page_arena_test.cc b/cpp/test/common/allocator/page_arena_test.cc index 0d34e95d8..e146685cf 100644 --- a/cpp/test/common/allocator/page_arena_test.cc +++ b/cpp/test/common/allocator/page_arena_test.cc @@ -55,6 +55,37 @@ TEST(PageArenaTest, AllocMoreThanPageSize) { page_arena.reset(); } +TEST(PageArenaTest, OversizedAllocationTracksUsedBytesAndPreservesData) { + PageArena arena; + arena.init(64, MOD_DEFAULT); + char* large = arena.alloc(256); + ASSERT_NE(large, nullptr); + memset(large, 'x', 256); + ASSERT_EQ(arena.get_total_used_bytes(), 256); + + char* small = arena.alloc(8); + ASSERT_NE(small, nullptr); + memset(small, 'y', 8); + EXPECT_EQ(arena.get_total_used_bytes(), 264); + EXPECT_EQ(arena.TEST_get_page_count(), 2); + for (int i = 0; i < 256; i++) { + ASSERT_EQ(large[i], 'x'); + } + arena.reset(); + EXPECT_EQ(arena.get_total_used_bytes(), 0); +} + +TEST(PageArenaTest, ConsecutiveOversizedAllocationsTrackUsedBytes) { + PageArena arena; + arena.init(64, MOD_DEFAULT); + ASSERT_NE(arena.alloc(256), nullptr); + ASSERT_NE(arena.alloc(512), nullptr); + ASSERT_EQ(arena.get_total_used_bytes(), 768); + EXPECT_EQ(arena.TEST_get_page_count(), 2); + ASSERT_NE(arena.alloc(8), nullptr); + EXPECT_EQ(arena.get_total_used_bytes(), 776); +} + struct MyStruct { double x; int64_t y; From 233e63e1ed895ad229b41c77901e1439eb723729 Mon Sep 17 00:00:00 2001 From: Xinyao Zhang <43081360+zhangxinyao88@users.noreply.github.com> Date: Sun, 25 Oct 2026 09:56:39 -0400 Subject: [PATCH 2/2] Provision pinned clang-format for Linux CI jobs Install clang-format 17.0.6 in a runner-local virtual environment rather than assuming /usr/bin/clang-format-17 exists. Keep the Python 3.9 Linux job on Ubuntu 22.04, where setup-python provides its binary, while retaining all nine Python matrix combinations. Generated-by: OpenAI Codex --- .github/workflows/unit-test-cpp.yml | 14 ++++++++++---- .github/workflows/unit-test-python.yml | 13 +++++++++++-- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/.github/workflows/unit-test-cpp.yml b/.github/workflows/unit-test-cpp.yml index 7a0605c8b..3e46d6920 100644 --- a/.github/workflows/unit-test-cpp.yml +++ b/.github/workflows/unit-test-cpp.yml @@ -80,6 +80,12 @@ jobs: - name: Checkout repository uses: actions/checkout@v7 + - name: Set up Python for clang-format + if: runner.os == 'Linux' + uses: actions/setup-python@v7 + with: + python-version: "3.11" + - name: Set up JDK 17 uses: actions/setup-java@v6.0.1 with: @@ -121,10 +127,10 @@ jobs: elif command -v yum >/dev/null 2>&1; then sudo yum install -y libuuid-devel fi - sudo update-alternatives --install /usr/bin/clang-format clang-format /usr/bin/clang-format-17 100 - sudo update-alternatives --set clang-format /usr/bin/clang-format-17 - sudo apt-get update - sudo apt-get install -y uuid-dev + python -m venv "$RUNNER_TEMP/clang-format" + "$RUNNER_TEMP/clang-format/bin/python" -m pip install --only-binary=:all: clang-format==17.0.6 + "$RUNNER_TEMP/clang-format/bin/clang-format" --version + echo "$RUNNER_TEMP/clang-format/bin" >> "$GITHUB_PATH" elif [[ "$RUNNER_OS" == "Windows" ]]; then choco install llvm --version 17.0.6 --force else diff --git a/.github/workflows/unit-test-python.yml b/.github/workflows/unit-test-python.yml index b01c09341..854774034 100644 --- a/.github/workflows/unit-test-python.yml +++ b/.github/workflows/unit-test-python.yml @@ -45,6 +45,13 @@ jobs: matrix: os: [ ubuntu-latest, macos-latest, windows-latest ] python-version: ["3.9", "3.11", "3.14"] + exclude: + - os: ubuntu-latest + python-version: "3.9" + include: + # Python 3.9 has no setup-python build for Ubuntu 26.04. + - os: ubuntu-22.04 + python-version: "3.9" runs-on: ${{ matrix.os }} steps: @@ -92,8 +99,10 @@ jobs: shell: bash run: | if [[ "$RUNNER_OS" == "Linux" ]]; then - sudo update-alternatives --install /usr/bin/clang-format clang-format /usr/bin/clang-format-17 100 - sudo update-alternatives --set clang-format /usr/bin/clang-format-17 + python -m venv "$RUNNER_TEMP/clang-format" + "$RUNNER_TEMP/clang-format/bin/python" -m pip install --only-binary=:all: clang-format==17.0.6 + "$RUNNER_TEMP/clang-format/bin/clang-format" --version + echo "$RUNNER_TEMP/clang-format/bin" >> "$GITHUB_PATH" sudo apt-get update sudo apt-get install -y uuid-dev elif [[ "$RUNNER_OS" == "Windows" ]]; then