Commit 747b70a2 authored by jan.koester's avatar jan.koester
Browse files

tet

parent c1bb0dfd
Loading
Loading
Loading
Loading
+10 −0
Changes for CMakeLists.txt: 10 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -71,6 +71,16 @@ add_executable(proxyplus src/main.cpp)
target_link_libraries(proxyplus PRIVATE proxyplus_core)
target_compile_definitions(proxyplus PRIVATE
    PROXYPLUS_DEFAULT_STATIC_DIR="${CMAKE_INSTALL_PREFIX}/share/proxyplus/admin")
# ENABLE_EXPORTS (-rdynamic/--export-dynamic): IPlugin and its extension-point interfaces
# (see src/plugin/PluginApi.h) have no out-of-line virtual function, so their vtable/typeinfo
# get vague (weak) linkage rather than one strong definition -- proxyplus's own copy (pulled
# in via CertificateManager.cpp etc.) needs to be visible in the dynamic symbol table so the
# dynamic linker can merge it with the copy inside each dlopen()'d plugin .so. Without this,
# dynamic_cast<ICertificateProviderPlugin*> (used by PluginManager::collect<Iface>()) finds
# no match even though the plugin genuinely implements the interface -- confirmed to matter
# in practice on OpenBSD/clang/libc++abi; virtual calls (e.g. IPlugin::name()) work regardless
# since those go through the vtable pointer directly, not RTTI.
set_target_properties(proxyplus PROPERTIES ENABLE_EXPORTS ON)

install(TARGETS proxyplus RUNTIME DESTINATION bin)
install(DIRECTORY admin/static/ DESTINATION share/proxyplus/admin)
+1 −10
Changes for src/plugin/PluginManager.cpp: 1 added line, 10 removed lines.
Original line number Diff line number Diff line
@@ -28,16 +28,7 @@ void PluginManager::loadDirectory(const std::string &dir, const std::map<std::st

        std::string path = dir + "/" + fname;

        // RTLD_GLOBAL, not RTLD_LOCAL: IPlugin and its extension-point interfaces (see
        // PluginApi.h) have no out-of-line virtual function, so their vtable/typeinfo get
        // vague (weak) linkage rather than one strong definition. Under RTLD_LOCAL every
        // dlopen'd plugin -- and the host binary -- carries its own private copy, and
        // dynamic_cast (used by collect<Iface>() below) compares typeinfo identity across
        // images and finds no match, even though the plugin genuinely implements the
        // interface (virtual calls still work fine since those go through the vtable
        // pointer directly, not RTTI). RTLD_GLOBAL lets the dynamic linker share one copy
        // of those weak symbols across the whole process instead.
        void *handle = ::dlopen(path.c_str(), RTLD_NOW | RTLD_GLOBAL);
        void *handle = ::dlopen(path.c_str(), RTLD_NOW | RTLD_LOCAL);

        if (!handle) {
            _errors.push_back(fname + ": " + std::string(::dlerror() ? ::dlerror() : "dlopen failed"));