On Tue, 29 Jun 2021, 17:24 Oleg Smolsky, <osmolsky@xxxxxxxxxxxx> wrote: > > > On Tue, Jun 29, 2021 at 8:42 AM Oleg Smolsky <osmolsky@xxxxxxxxxxxx> > wrote: > >> >> >> On Tue, Jun 29, 2021 at 8:39 AM Oleg Smolsky <osmolsky@xxxxxxxxxxxx> >> wrote: >> >>> I am using `g++` to link in both working and failing cases. >>> >> >> The peculiar thing is that the linking issue goes away when I change the >> reproducer slightly: avoid linking the gcc10-built lib or avoid using >> std::unordered_map. Either thing is OK by itself... >> > > I've just tried to create a stand-alone test case (with the .so compiled > separately with a different compiler) but cannot reproduce the issue. > > However, I have the following clues from the shared libs: > > The GCC10-built lib: > > $ objdump -T /opt/3p/lib/libzmq.so | c++filt | grep __throw_ > 0000000000000000 DF *UND* 0000000000000000 GLIBCXX_3.4 > std::__throw_bad_alloc() > 0000000000000000 DF *UND* 0000000000000000 GLIBCXX_3.4 > std::__throw_length_error(char const*) > 0000000000000000 DF *UND* 0000000000000000 GLIBCXX_3.4 > std::__throw_logic_error(char const*) > 0000000000000000 DF *UND* 0000000000000000 GLIBCXX_3.4.20 > std::__throw_out_of_range_fmt(char const*, ...) > > The GCC11-built lib: > > $ objdump -T /opt/3p/lib/libzmq.so-gcc11 | c++filt | grep __throw_ > 0000000000000000 DF *UND* 0000000000000000 GLIBCXX_3.4 > std::__throw_bad_alloc() > 0000000000000000 DF *UND* 0000000000000000 GLIBCXX_3.4 > std::__throw_length_error(char const*) > 0000000000000000 DF *UND* 0000000000000000 GLIBCXX_3.4 > std::__throw_logic_error(char const*) > 0000000000000000 DF *UND* 0000000000000000 GLIBCXX_3.4.29 > std::__throw_bad_array_new_length() > 0000000000000000 DF *UND* 0000000000000000 GLIBCXX_3.4.20 > std::__throw_out_of_range_fmt(char const*, ...) > > Here we can see that `std::__throw_bad_array_new_length()` is only > present in the new build. > And that symbol is defined in libstdc++.so.6.0.29 so if you link with the g++ from GCC 11 then it should work. Which tells me that either you're not linking with g++ (which you already confirmed), or you're using the g++ from GCC 10, or you have a -L option that causes an older libstdc++.so to be found before the correct one. You should be able to easily verify that for yourself. Run objdump on the libstdc++.so from GCC 11 and confirm it contains the "missing" symbol. Add -v to your link command, to check which GCC executables are being run, and what linker paths they use. Add -Wl,--trace to your linker command to see the names of files as the linker processes them, to see which libstdc++.so or libstdc++.a is being found. Add -Wl,--trace-symbol=_ZSt28__throw_bad_array_new_lengthv to see all the input files that contain the missing symbol.