Skip to content

Commit

Permalink
Fix crash when building with _GLIBCXX_USE_CXX11_ABI=0 (#686)
Browse files Browse the repository at this point in the history
**Issue:**
A user had been building aws-crt-cpp with `CXXFLAGS=-D_GLIBCXX_USE_CXX11_ABI=0`, and that worked fine until the recent change where we started hiding symbols by default (PR #666)

With symbols hidden by default, and `_GLIBCXX_USE_CXX11_ABI=0`, tests would crash in the destructor of `Aws::Crt::String` (which is `std::string` with a custom allocator).

**Description of changes:**
Don't hide symbols when building for the ancient glibcxx ABI.

I don't 100% understand why this fixes the issue, but the situation is esoteric enough that it doesn't seem worth spending more days on this problem.

**Background**
See: https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html
GCC had to introduce a new ABI for C++11 which removed the copy-on-write optimization for strings, which is forbidden in C++11 and later (new ABI uses a small-string optimization instead). But GCC let users manually set `_GLIBCXX_USE_CXX11_ABI=0` so they could opt back into the old ABI and continue working with libraries compiled for C++03.

I don't think GCC intended devs to continue using this 10 years later, but some people are, because the old copy-on-write optimization has less memory usage.
  • Loading branch information
graebm authored Nov 28, 2024
1 parent 9ffe4ef commit 5478ce2
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 4 deletions.
10 changes: 9 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ env:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
linux-compat-use-openssl:
runs-on: ubuntu-22.04 # latest
Expand Down Expand Up @@ -143,6 +143,14 @@ jobs:
aws s3 cp s3://aws-crt-test-stuff/ci/${{ env.BUILDER_VERSION }}/linux-container-ci.sh ./linux-container-ci.sh && chmod a+x ./linux-container-ci.sh
./linux-container-ci.sh ${{ env.BUILDER_VERSION }} aws-crt-${{ env.LINUX_BASE_IMAGE }} build -p ${{ env.PACKAGE_NAME }} --compiler=${{ matrix.compiler }} --cmake-extra=-DBUILD_SHARED_LIBS=ON
linux-glibcxx-ancient-abi:
runs-on: ubuntu-24.04 # latest
steps:
- name: Build ${{ env.PACKAGE_NAME }}
run: |
aws s3 cp s3://aws-crt-test-stuff/ci/${{ env.BUILDER_VERSION }}/linux-container-ci.sh ./linux-container-ci.sh && chmod a+x ./linux-container-ci.sh
./linux-container-ci.sh ${{ env.BUILDER_VERSION }} aws-crt-${{ env.LINUX_BASE_IMAGE }} build -p ${{ env.PACKAGE_NAME }} --compiler=gcc-11 --cmake-extra=-DBUILD_SHARED_LIBS=ON --cmake-extra=-DCMAKE_CXX_FLAGS=-D_GLIBCXX_USE_CXX11_ABI=0
linux-openssl-static:
runs-on: ubuntu-22.04 # latest
steps:
Expand Down
16 changes: 13 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -298,9 +298,19 @@ set_target_properties(${PROJECT_NAME} PROPERTIES LINKER_LANGUAGE CXX)
set_target_properties(${PROJECT_NAME} PROPERTIES CXX_STANDARD ${CMAKE_CXX_STANDARD})

# Hide symbols by default
# Except for ancient GCC, because it leads to crashes in shared-lib builds
# see: https://github.com/awslabs/aws-crt-cpp/pull/675
if(NOT (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "5.0"))
# Except where it causes problems, and the situation is weird enough that it's not worth investigating further.
#
# We've seen people set _GLIBCXX_USE_CXX11_ABI=0 which forces GCC to use it's pre-C++11 string implementation,
# which leads to crashes on shared-lib builds. Search every variant of CXX_FLAGS to see if it's set.
string(FIND "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_DEBUG} ${CMAKE_CXX_FLAGS_RELEASE} ${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${CMAKE_CXX_FLAGS_MINSIZEREL}"
"-D_GLIBCXX_USE_CXX11_ABI=0" found_ancient_abi_flag)
if(found_ancient_abi_flag GREATER -1)
message(WARNING "_GLIBCXX_USE_CXX11_ABI=0 is set. Making all symbols visible to prevent weird crashes")
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "5.0")
# Ancient GCC leads to crashes in shared-lib builds
# see: https://github.com/awslabs/aws-crt-cpp/pull/675
message(WARNING "Ancient compiler (${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}). Making all symbols visible to prevent weird crashes")
else()
set_target_properties(${PROJECT_NAME} PROPERTIES CXX_VISIBILITY_PRESET hidden VISIBILITY_INLINES_HIDDEN ON)
endif()

Expand Down

0 comments on commit 5478ce2

Please sign in to comment.