Skip to content

Commit 1e547f0

Browse files
Copilotachamayou
andauthored
Drop libc++ (USE_LIBCXX) support (#7850)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: achamayou <4016369+achamayou@users.noreply.github.com> Co-authored-by: Amaury Chamayou <amchamay@microsoft.com> Co-authored-by: Amaury Chamayou <amaury@xargs.fr>
1 parent 575b734 commit 1e547f0

20 files changed

Lines changed: 160 additions & 103 deletions

.github/workflows/long-test.yml

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -172,16 +172,13 @@ jobs:
172172
run: |
173173
set -ex
174174
./scripts/setup-ci.sh
175-
# This run requires libc++ to run with hardening mode
176-
tdnf -y install libcxx-devel libunwind-devel
177175
178176
- name: "Build"
179177
run: |
180178
git config --global --add safe.directory /__w/CCF/CCF
181179
mkdir build
182180
cd build
183-
# Use libc++ to enable hardening/bounds checking during tests
184-
cmake -GNinja -DCMAKE_BUILD_TYPE=Debug -DLONG_TESTS=ON -DUSE_LIBCXX=ON -DUSE_SNMALLOC=OFF ..
181+
cmake -GNinja -DCMAKE_BUILD_TYPE=Debug -DGLIBCXX_DEBUG=ON -DLONG_TESTS=ON ..
185182
ninja
186183
187184
- name: "Test"
@@ -197,7 +194,7 @@ jobs:
197194
mkdir -p build_fuzz
198195
cd build_fuzz
199196
rm -f CMakeCache.txt
200-
cmake -GNinja -DFUZZING=ON -DSAN=ON -DUSE_LIBCXX=ON -DUSE_SNMALLOC=OFF ..
197+
cmake -GNinja -DFUZZING=ON -DSAN=ON -DUSE_SNMALLOC=OFF ..
201198
ninja cbor_fuzz_test
202199
mkdir -p /tmp/cbor_fuzz_live
203200
./cbor_fuzz_test /tmp/cbor_fuzz_live ../src/crypto/test/cbor_fuzz_corpus -max_total_time=60

CHANGELOG.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,18 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
99

1010
[7.0.3]: https://github.com/microsoft/CCF/releases/tag/ccf-7.0.3
1111

12-
### Fixed
12+
### Added
1313

14-
- On a joiner's first attempt, the primary now requires the joiner's startup seqno to be at least as recent as the primary's latest committed snapshot on disk, preventing snapshot-less joiners from replaying the entire ledger (#7844).
14+
- Added a `GLIBCXX_DEBUG` CMake option to enable libstdc++ debug mode (`_GLIBCXX_DEBUG`) for CCF and its tests. When set, end-to-end tests run via `ConcurrentRunner` are throttled to fewer parallel suites to compensate for the slower runtime, and the `submit` binary (which links against Arrow) is disabled because Arrow is not built with `_GLIBCXX_DEBUG` (#7850).
15+
16+
### Removed
17+
18+
- The `USE_LIBCXX` CMake option and all associated libc++/libc++abi build and packaging support have been removed. CCF now builds exclusively with libstdc++ (#7850).
1519

1620
### Changed
1721

1822
- Upgraded QuickJS from 2024-01-13 to 2025-09-13 (#7849).
23+
- On a joiner's first attempt, the primary now requires the joiner's startup seqno to be at least as recent as the primary's latest committed snapshot on disk, preventing snapshot-less joiners from replaying the entire ledger (#7844).
1924

2025
## [7.0.2]
2126

CMakeLists.txt

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,17 @@ option(LONG_TESTS "Enable long end-to-end tests" OFF)
9393
option(USE_SNMALLOC "Link against snmalloc" ON)
9494
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/snmalloc.cmake)
9595

96-
# Useful for debugging with libc++ hardening options
97-
option(USE_LIBCXX "Use libc++ instead of libstdc++" OFF)
98-
9996
option(CLANG_TIDY "Run clang-tidy on the codebase" OFF)
97+
98+
option(
99+
GLIBCXX_DEBUG
100+
"Enable libstdc++ debug mode (_GLIBCXX_DEBUG). Disables the submit binary (which links against Arrow, not built with _GLIBCXX_DEBUG)."
101+
OFF
102+
)
103+
if(GLIBCXX_DEBUG)
104+
add_compile_definitions(_GLIBCXX_DEBUG)
105+
endif()
106+
100107
# Must happen before tools.cmake is included
101108
if(CLANG_TIDY)
102109
find_program(
@@ -198,7 +205,6 @@ add_ccf_static_library(
198205
${TLS_LIBRARY}
199206
${CMAKE_DL_LIBS}
200207
${CMAKE_THREAD_LIBS_INIT}
201-
${LINK_LIBCXX}
202208
ccfcrypto
203209
curl
204210
http_parser
@@ -291,12 +297,6 @@ add_ccf_static_library(
291297
${CCF_DIR}/src/tasks/worker.cpp
292298
)
293299
target_link_libraries(ccf_tasks PRIVATE ${CMAKE_DL_LIBS})
294-
if(USE_LIBCXX)
295-
# worker.cpp uses backtrace() which, under libc++, resolves through libunwind.
296-
# On systems where libunwind is built with LZMA support (e.g. Azure Linux),
297-
# this creates a transitive dependency on liblzma.
298-
target_link_libraries(ccf_tasks PRIVATE lzma)
299-
endif()
300300

301301
# Common test args for Python scripts starting up CCF networks
302302
set(
@@ -420,7 +420,6 @@ add_ccf_static_library(
420420
ccf
421421
SRCS ${CCF_IMPL_SOURCE}
422422
LINK_LIBS
423-
${LINK_LIBCXX}
424423
http_parser
425424
ccf_js
426425
ccf_endpoints
@@ -901,10 +900,9 @@ if(BUILD_TESTS)
901900
src/node/test/merkle_mem.cpp
902901
${CCF_DIR}/src/enclave/thread_local.cpp
903902
)
904-
target_compile_options(merkle_mem PRIVATE ${COMPILE_LIBCXX})
905903
target_link_libraries(
906904
merkle_mem
907-
PRIVATE ${CMAKE_THREAD_LIBS_INIT} ${LINK_LIBCXX} ccfcrypto
905+
PRIVATE ${CMAKE_THREAD_LIBS_INIT} ccfcrypto
908906
)
909907

910908
# Raft driver and scenario test
@@ -941,7 +939,7 @@ if(BUILD_TESTS)
941939
)
942940
endif()
943941

944-
if(NOT TSAN AND NOT USE_LIBCXX)
942+
if(NOT TSAN)
945943
# Picobench benchmarks
946944
add_picobench(map_bench SRCS src/ds/test/map_bench.cpp)
947945
add_picobench(logger_bench SRCS src/ds/test/logger_bench.cpp)
@@ -1433,7 +1431,7 @@ install(
14331431
DESTINATION ${CMAKE_INSTALL_PREFIX}/cmake
14341432
)
14351433

1436-
if(NOT USE_LIBCXX)
1437-
# Perf tool executable
1434+
# Perf tool executable (requires Arrow/Parquet, not compatible with GLIBCXX_DEBUG)
1435+
if(NOT GLIBCXX_DEBUG)
14381436
include(${CCF_DIR}/tests/perf-system/submitter/CMakeLists.txt)
14391437
endif()

cmake/ccf_app.cmake

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,6 @@
11
# Copyright (c) Microsoft Corporation. All rights reserved.
22
# Licensed under the Apache 2.0 License.
33

4-
if(USE_LIBCXX)
5-
list(APPEND COMPILE_LIBCXX -stdlib=libc++)
6-
list(APPEND LINK_LIBCXX -lc++ -lc++abi -stdlib=libc++)
7-
8-
if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
9-
add_compile_options(-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_DEBUG)
10-
elseif("${CMAKE_BUILD_TYPE}" STREQUAL "Release")
11-
add_compile_options(-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_FAST)
12-
endif()
13-
endif()
14-
154
# Enclave library wrapper
165
function(add_ccf_app name)
176
cmake_parse_arguments(
@@ -74,9 +63,7 @@ function(add_ccf_static_library name)
7463

7564
add_library(${name} STATIC ${PARSED_ARGS_SRCS})
7665

77-
target_link_libraries(${name} PUBLIC ${PARSED_ARGS_LINK_LIBS} ${LINK_LIBCXX})
78-
79-
target_compile_options(${name} PUBLIC ${COMPILE_LIBCXX})
66+
target_link_libraries(${name} PUBLIC ${PARSED_ARGS_LINK_LIBS})
8067

8168
set_property(TARGET ${name} PROPERTY POSITION_INDEPENDENT_CODE ON)
8269

cmake/common.cmake

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,12 @@ endfunction()
2929
# Unit test wrapper
3030
function(add_unit_test name)
3131
add_executable(${name} ${CCF_DIR}/src/enclave/thread_local.cpp ${ARGN})
32-
target_compile_options(${name} PRIVATE ${COMPILE_LIBCXX})
3332
target_include_directories(
3433
${name}
3534
PRIVATE src ${CCFCRYPTO_INC} ${CCF_DIR}/3rdparty/test
3635
)
3736
enable_coverage(${name})
38-
target_link_libraries(${name} PRIVATE ${LINK_LIBCXX} ccfcrypto -pthread)
37+
target_link_libraries(${name} PRIVATE ccfcrypto -pthread)
3938
add_san(${name})
4039

4140
add_test(NAME ${name} COMMAND ${name})
@@ -52,33 +51,42 @@ function(add_unit_test name)
5251
add_san_test_properties(${name})
5352
endfunction()
5453

55-
# Fuzz test wrapper (requires -DFUZZING=ON -DUSE_LIBCXX=ON)
54+
# Fuzz test wrapper (requires -DFUZZING=ON)
5655
function(add_fuzz_test name)
57-
if(NOT USE_LIBCXX)
58-
message(
59-
FATAL_ERROR
60-
"Fuzz targets require USE_LIBCXX=ON to avoid UBSAN false positives from libstdc++ shared_ptr"
61-
)
62-
endif()
63-
6456
add_executable(${name} ${CCF_DIR}/src/enclave/thread_local.cpp ${ARGN})
65-
target_compile_options(${name} PRIVATE ${COMPILE_LIBCXX} -fsanitize=fuzzer)
57+
target_compile_options(${name} PRIVATE -fsanitize=fuzzer)
6658
target_link_options(${name} PRIVATE -fsanitize=fuzzer)
6759
target_include_directories(${name} PRIVATE src ${CCFCRYPTO_INC})
68-
target_link_libraries(${name} PRIVATE ${LINK_LIBCXX} -pthread)
60+
target_link_libraries(${name} PRIVATE -pthread)
6961
add_san(${name})
62+
# UBSan's vptr check fires inside libstdc++'s
63+
# std::_Sp_counted_ptr_inplace<T,A,_Lp>::_Sp_counted_ptr_inplace ctor
64+
# (used by std::make_shared) when the inplace control block is being
65+
# constructed: that ctor reinterpret_casts uninitialised memory to T*
66+
# in order to call std::allocator_traits<T>::construct, and UBSan reads
67+
# whatever bytes happen to be there as a vptr. The same false positive
68+
# is documented and explicitly excluded by CFI in
69+
# compiler-rt/lib/cfi/cfi_ignorelist.txt
70+
# (entry: "fun:_ZNSt23_Sp_counted_ptr_inplace*"); UBSan has no
71+
# equivalent ignorelist for vptr. See LLVM issue #48337 for context.
72+
# The diagnostic is reliably reproducible when libclang_rt.fuzzer is
73+
# linked in, because libfuzzer's allocator activity leaves non-zero
74+
# bytes in the freshly returned heap slot.
75+
# Fuzz binaries don't exercise vtable correctness, so disabling vptr
76+
# is the simplest workaround.
77+
target_compile_options(${name} PRIVATE -fno-sanitize=vptr)
78+
target_link_options(${name} PRIVATE -fno-sanitize=vptr)
7079
endfunction()
7180

7281
# Test binary wrapper
7382
function(add_test_bin name)
7483
add_executable(${name} ${CCF_DIR}/src/enclave/thread_local.cpp ${ARGN})
75-
target_compile_options(${name} PRIVATE ${COMPILE_LIBCXX})
7684
target_include_directories(
7785
${name}
7886
PRIVATE src ${CCFCRYPTO_INC} ${CCF_DIR}/3rdparty/test
7987
)
8088
enable_coverage(${name})
81-
target_link_libraries(${name} PRIVATE ${LINK_LIBCXX} ccfcrypto)
89+
target_link_libraries(${name} PRIVATE ccfcrypto)
8290
add_san(${name})
8391
endfunction()
8492

@@ -135,6 +143,14 @@ function(add_e2e_test)
135143
)
136144
endif()
137145

146+
if(GLIBCXX_DEBUG)
147+
set_property(
148+
TEST ${PARSED_ARGS_NAME}
149+
APPEND
150+
PROPERTY ENVIRONMENT "CCF_GLIBCXX_DEBUG=1"
151+
)
152+
endif()
153+
138154
if("${PARSED_ARGS_LABEL}" STREQUAL "partitions")
139155
set_property(
140156
TEST ${PARSED_ARGS_NAME}

cmake/cpack_ccfapp.cmake

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,5 @@ set(
1616
CCF_RPM_DEPENDENCIES
1717
"${CCF_RPM_DEPENDENCIES}, curl >= ${CURL_MINIMAL_VERSION}"
1818
)
19-
set(
20-
CCF_RPM_DEPENDENCIES
21-
"${CCF_RPM_DEPENDENCIES}, libcxxabi >= ${CLANG_AND_LIBCXXABI_MINIMAL_VERSION}"
22-
)
2319

2420
set(CPACK_CCF_RUNTIME_REQUIRES "${CCF_RPM_DEPENDENCIES}")

cmake/cpack_settings.cmake

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,12 @@ set(
3434
# + build toolchain
3535
set(
3636
CCF_RPM_DEPENDENCIES
37-
"${CCF_RPM_DEPENDENCIES}, cmake >= 3.21, build-essential >= 3.0, clang >= ${CLANG_AND_LIBCXXABI_MINIMAL_VERSION}, ninja-build >= 1.11.1"
37+
"${CCF_RPM_DEPENDENCIES}, cmake >= 3.21, build-essential >= 3.0, clang >= ${CLANG_MINIMAL_VERSION}, ninja-build >= 1.11.1"
3838
)
3939
# + runtime dependencies
4040
set(
4141
CCF_RPM_DEPENDENCIES
42-
"${CCF_RPM_DEPENDENCIES}, libuv-devel >= ${LIBUV_MINIMAL_VERSION}, curl-devel >= ${CURL_MINIMAL_VERSION}, libcxxabi-devel >= ${CLANG_AND_LIBCXXABI_MINIMAL_VERSION}"
42+
"${CCF_RPM_DEPENDENCIES}, libuv-devel >= ${LIBUV_MINIMAL_VERSION}, curl-devel >= ${CURL_MINIMAL_VERSION}"
4343
)
4444
# + alter name
4545
set(CPACK_PACKAGE_NAME "${CPACK_PACKAGE_NAME}_devel")

cmake/cpack_versions_pin.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ set(OPENSSL_MINIMAL_VERSION "3.3.0")
55
set(NGHTTP2_MINIMAL_VERSION "1.40.0")
66
set(LIBUV_MINIMAL_VERSION "1.34.2")
77
set(CURL_MINIMAL_VERSION "7.68.0")
8-
set(CLANG_AND_LIBCXXABI_MINIMAL_VERSION "18.1.2")
8+
set(CLANG_MINIMAL_VERSION "18.1.2")

cmake/crypto.cmake

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,6 @@ find_library(TLS_LIBRARY ssl)
3636
add_library(ccfcrypto STATIC ${CCFCRYPTO_SRC})
3737
add_san(ccfcrypto)
3838
add_tidy(ccfcrypto)
39-
target_compile_options(ccfcrypto PUBLIC ${COMPILE_LIBCXX})
40-
target_link_options(ccfcrypto PUBLIC ${LINK_LIBCXX})
4139

4240
target_link_libraries(ccfcrypto PUBLIC crypto ssl evercbor)
4341
target_link_libraries(

0 commit comments

Comments
 (0)