https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97908
Bug ID: 97908 Summary: Should _ZTI and _ZTS symbols be marked GNU_UNIQUE Product: gcc Version: 11.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: jengelh at inai dot de Target Milestone: --- » cat libx.cpp #include <typeinfo> class Foobar {}; extern "C" { const char *makename(); } const char *makename() { Foobar f; return typeid(f).name(); } » cat m.cpp #include <cstdio> #include <dlfcn.h> int main() { auto hnd = dlopen("./libx.so", RTLD_NOW); auto f = reinterpret_cast<const char *(*)()>(dlsym(hnd, "makename")); auto name = f(); printf("%s\n", name); dlclose(hnd); printf("%s\n", name); } » g++-11 libx.cpp -shared -fPIC -ggdb3 -o libx.so; g++ m.cpp -fPIC -ggdb3 -Wall -ldl » ./a.out 6Foobar Segmentation fault (core dumped) » g++-11 -v gcc version 11.0.0 20201112 (experimental) [revision 876b45db81a708616d70b1ab66b71bd503809c21] (SUSE Linux) I do not know if this is even supposed to work. dlopen/dlclose is outside the scope of the C++ standard, and POSIX (where dlopen comes from) does not mention C++ during dlopen. However, this _alternate_ libx.cpp makes the program work: #include <typeinfo> struct Foobar { static constexpr char __tag[sizeof(std::type_info)] = { }; }; extern "C" { const char *makename(); } const char *makename() { Foobar f; return typeid(f).name(); } const char *helperfunc() { Foobar f; return f.__tag; } __tag is emitted into the object file as a STB_GNU_UNIQUE symbol, which happens to implicate RTLD_NODELETE for dlopen. So, if __tag is getting the "unique" treatment to fulfill some guarantee, should typeinfo variables (_ZTS* and _ZTI*) not get the same treatment, for the same reasons?