https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82366

--- Comment #15 from Karol Zwolak <karolzwolak7 at gmail dot com> ---
After more investigation by my colleague, it turned out to be a not a bug, but
rather a misuse of RTLD_DEEPBIND flag when loading a shared library. 
This flag alters symbol resolution behavior by prioritizing symbols inside the
shared library over those in the global namespace.

In this case, libstdc++ is dynamically linked in both the library and the
binary. When RTLD_DEEPBIND is used, library resolves its C++ standard library
symbols internally—even if the main executable has already loaded and
initialized a different instance of libstdc++.

I attached a minimal reproduction for my case. Note that this crash isn't
exclusive to std::regex, replacing the uses of regex with use of std::cout
crashes as well in this instance (although with segfault).

The gist of the reproduction:

lib.cpp:`
#include <regex>

extern "C" void call_from_main() {
  std::regex regex("a"); // crashes with std::bad_cast
}
`
main.cpp:`
#include <dlfcn.h>
#include <regex>

typedef void (*lib_func_t)();

int main() {
  std::regex regex("a");

  // Remove RTLD_DEEPBIND to avoid std::bad_cast
  void *handle = dlopen("./lib.so", RTLD_NOW | RTLD_DEEPBIND);
  lib_func_t func = (lib_func_t)dlsym(handle, "call_from_main");

  func(); // this is gonna crash with std::bad_cast

  dlclose(handle);
  return 0;
}
`
compile:
g++ -fPIC -shared lib.cpp -o lib.so -O0
g++ main.cpp -o repro -O0

run:
LD_LIBRARY_PATH=. ./repro

Reply via email to