@@ -162,6 +162,27 @@ add_dependencies(gluten jni_proto)
162162if (NOT CMAKE_SYSTEM_NAME MATCHES "Darwin" )
163163 target_link_options (
164164 gluten PRIVATE -Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/symbols.map )
165+ # libgluten statically links libstdc++/libgcc (see dev/vcpkg/toolchain.cmake's
166+ # -static-libstdc++ -static-libgcc). The version script above has no "local:
167+ # *" catch-all (it must keep Arrow/substrait/etc. exported for libvelox to
168+ # resolve against), so by default the bundled gcc-13 C++ runtime symbols also
169+ # stay in libgluten's dynamic symbol table -- and the std::locale::id objects
170+ # that index the facet table are emitted as STB_GNU_UNIQUE. When another
171+ # libstdc++ is already loaded in the process (the system gcc-11 libstdc++.so.6
172+ # pulled in by the JVM inside the centos-9 image), the loader collapses those
173+ # unique ids into one process-wide definition; libgluten then indexes its
174+ # gcc-13 facet table with the system id value, reads a bogus num_put/codecvt
175+ # facet pointer, and crashes with SIGSEGV during Velox backend initialization
176+ # (do_unshift, si_addr=0x30). -Bsymbolic does not help because STB_GNU_UNIQUE
177+ # overrides it. --exclude-libs demotes the symbols coming from the named C++
178+ # runtime archives to STB_LOCAL, dropping them from the dynamic symbol table
179+ # entirely (this also clears their STB_GNU_UNIQUE binding) so they can neither
180+ # interpose nor be interposed -- the same isolation libvelox already gets from
181+ # its "local: *" map. Symbols from the other static deps (Arrow, substrait,
182+ # ...) come from different archives and stay exported.
183+ target_link_options (
184+ gluten PRIVATE -Wl,--exclude-libs,libstdc++.a -Wl,--exclude-libs,libgcc.a
185+ -Wl,--exclude-libs,libgcc_eh.a )
165186endif ()
166187
167188if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.0)
0 commit comments