Skip to content

Fix yaml-cpp exception symbol visibility#592

Merged
anderkve merged 3 commits into
GambitBSM:masterfrom
ChrisJChang:YAML_CPP_undefined_symbol
May 8, 2026
Merged

Fix yaml-cpp exception symbol visibility#592
anderkve merged 3 commits into
GambitBSM:masterfrom
ChrisJChang:YAML_CPP_undefined_symbol

Conversation

@ChrisJChang
Copy link
Copy Markdown
Collaborator

This PR fixes an intermittent runtime error where backends or scanner plugins loaded via dlopen cannot resolve the RTTI typeinfo for YAML::BadConversion (and related exception classes).

Root cause: Two interacting gaps in the build system:

GAMBIT sets CMAKE_CXX_VISIBILITY_PRESET hidden globally by default (whenever -rdynamic is absent from CMAKE_CXX_FLAGS). The yaml-cpp contrib library inherits this preset, so its symbols — including exception typeinfo — get compiled with hidden visibility.
Without -rdynamic, symbols from statically linked code are not placed in the executable's dynamic symbol table. Backends and scanner plugins loaded at runtime via dlopen(RTLD_LAZY) therefore cannot resolve yaml-cpp typeinfo, even though the exception classes carry the correct YAML_CPP_API / __attribute__((visibility("default"))) annotation.

The error is intermittent because it only manifests on builds where the user has not manually added -rdynamic to CMAKE_CXX_FLAGS.

Changes:

[contrib/yaml-cpp-0.6.2/CMakeLists.txt](https://github.com/ChrisJChang/gambit_code_testing/blob/YAML_CPP_undefined_symbol/contrib/yaml-cpp-0.6.2/CMakeLists.txt): Set CXX_VISIBILITY_PRESET default and VISIBILITY_INLINES_HIDDEN FALSE on the yaml-cpp target, overriding the project-wide hidden preset specifically for this contrib library.
[cmake/utilities.cmake](https://github.com/ChrisJChang/gambit_code_testing/blob/YAML_CPP_undefined_symbol/cmake/utilities.cmake): Set ENABLE_EXPORTS TRUE on all GAMBIT executables. This is CMake's built-in mechanism for adding -rdynamic (Linux) / -export_dynamic (macOS), ensuring statically linked yaml-cpp symbols are exported into the executable's dynamic symbol table for use by dlopen'd plugins.

Verified by confirming _ZTIN4YAML13BadConversionE appears in nm -D gambit after the fix (previously absent), and that the scanner plugin shared libraries (e.g. libscanner_multinest_3.12.so) which reference this symbol as an undefined import can now resolve it at load time.

…13BadConversionE)

Two complementary fixes for the intermittent runtime error:

1. Set CXX_VISIBILITY_PRESET=default and VISIBILITY_INLINES_HIDDEN=FALSE on
   the yaml-cpp CMake target (contrib/yaml-cpp-0.6.2/CMakeLists.txt). GAMBIT
   enables CMAKE_CXX_VISIBILITY_PRESET=hidden globally by default (when no
   -rdynamic is in CMAKE_CXX_FLAGS), which would otherwise hide yaml-cpp
   exception RTTI even though YAML_CPP_API correctly applies
   __attribute__((visibility("default"))) to each exception class.

2. Set ENABLE_EXPORTS=TRUE on all GAMBIT executables (cmake/utilities.cmake).
   This adds -rdynamic (Linux) / -export_dynamic (macOS) to the executable
   link step, so yaml-cpp typeinfo symbols that are statically linked into the
   executable are exported into the dynamic symbol table and remain resolvable
   by backends and scanner plugins loaded at runtime via dlopen.

The error is intermittent because it only manifests when a user builds without
-rdynamic in CMAKE_CXX_FLAGS (the default), and when a dlopen'd backend or
plugin references yaml-cpp exception typeinfo that is not otherwise visible.

https://claude.ai/code/session_01PAuG5z7cdvGWuxbpWMn52L
@ChrisJChang ChrisJChang requested a review from anderkve May 8, 2026 09:55
@ChrisJChang ChrisJChang self-assigned this May 8, 2026
@ChrisJChang ChrisJChang added the bug label May 8, 2026
@ChrisJChang ChrisJChang changed the title Fix yaml-cpp exception symbol visibility (undefined symbol _ZTIN4YAML… Fix yaml-cpp exception symbol visibility May 8, 2026
claude added 2 commits May 8, 2026 13:39
Documents why ENABLE_EXPORTS is set via a target property rather than
CMAKE_CXX_FLAGS, how it interacts with the project-wide hidden visibility
preset to keep GAMBIT internals unexported, and the symbol interposition
behaviour to be aware of for third-party backends.

https://claude.ai/code/session_01PAuG5z7cdvGWuxbpWMn52L
@anderkve anderkve merged commit fe7d786 into GambitBSM:master May 8, 2026
1 check passed
@ChrisJChang ChrisJChang deleted the YAML_CPP_undefined_symbol branch May 8, 2026 13:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants