From aaca2b6e73b49dc0685eaa6e7d3933ca343395c0 Mon Sep 17 00:00:00 2001 From: PatTheMav Date: Sat, 23 Sep 2023 00:52:19 +0200 Subject: [PATCH] libobs: Fix duplicate symbol resolution for obs plugins By default duplicate non-static symbols loaded by dynamic libraries are de-duplicated by the dynamic library loader. This can lead to issues with statically linked libraries inside obs plugins if the symbols share their signature: Whichever plugin is loaded first gets to "set" the symbol (which can become problematic especially for C++ template functions). Using RTLD_LOCAL ensures that all symbols are hidden and can only be explicitly loaded using dlsym() which avoids this issue. Unfortunately due to the way scripting works in obs-studio, Python still needs to be loaded with RTLD_GLOBAL, hence the branch in the fix. --- libobs/util/platform-nix.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/libobs/util/platform-nix.c b/libobs/util/platform-nix.c index ac3b517b5..2fe19b9f5 100644 --- a/libobs/util/platform-nix.c +++ b/libobs/util/platform-nix.c @@ -83,7 +83,13 @@ void *os_dlopen(const char *path) dstr_cat(&dylib_name, ".so"); #ifdef __APPLE__ - void *res = dlopen(dylib_name.array, RTLD_LAZY | RTLD_FIRST); + int dlopen_flags = RTLD_LAZY | RTLD_FIRST; + if (dstr_find(&dylib_name, "Python")) { + dlopen_flags = dlopen_flags | RTLD_GLOBAL; + } else { + dlopen_flags = dlopen_flags | RTLD_LOCAL; + } + void *res = dlopen(dylib_name.array, dlopen_flags); #else void *res = dlopen(dylib_name.array, RTLD_LAZY); #endif