public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* Linking issue when mixing GCC10/GCC11 artifacts
@ 2021-06-29  4:55 Oleg Smolsky
  2021-06-29  5:32 ` Jonathan Wakely
  0 siblings, 1 reply; 10+ messages in thread
From: Oleg Smolsky @ 2021-06-29  4:55 UTC (permalink / raw)
  To: gcc-help

Hi, I've just hit a peculiar linking issue when using std::unordered_map,
C++17 and mixing some shared libs built with GCC10/11. Here is the linking
issue:

test.o: In function `__gnu_cxx::new_allocator<std:
:__detail::_Hash_node_base*>::allocate(unsigned long, void const*)':
/opt/gcc-11/include/c++/11.1.0/ext/new_allocator.h:110: undefined reference
to `std::__throw_bad_array_new_length()'
collect2: error: ld returned 1 exit status

The reproducer looks benign to me:

struct Thing { int a, b, c; };
 int main(int argc, char **argv) {
    std::unordered_map<unsigned int, Thing *> map;
    map[1] = new Thing;
}

I hit the linking issue when the reproducer is built with GCC11 and I
link libzmq.so.3 that was built with GCC10. This is all happening on a
64-bit Linux VM and I built both compilers on the same OS (Ubuntu 16). The
issue goes away when I rebuild the 3rd-party lib with GCC11... yet I am
failing to understand why this is happening... Is this an oversight in
libstdc++ that results in an ABI break?

Thanks in advance,
Oleg.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Linking issue when mixing GCC10/GCC11 artifacts
  2021-06-29  4:55 Linking issue when mixing GCC10/GCC11 artifacts Oleg Smolsky
@ 2021-06-29  5:32 ` Jonathan Wakely
  2021-06-29 15:39   ` [EXTERNAL] " Oleg Smolsky
  0 siblings, 1 reply; 10+ messages in thread
From: Jonathan Wakely @ 2021-06-29  5:32 UTC (permalink / raw)
  To: Oleg Smolsky; +Cc: gcc-help

On Tue, 29 Jun 2021, 05:58 Oleg Smolsky via Gcc-help, <gcc-help@gcc.gnu.org>
wrote:

> Hi, I've just hit a peculiar linking issue when using std::unordered_map,
> C++17 and mixing some shared libs built with GCC10/11. Here is the linking
> issue:
>
> test.o: In function `__gnu_cxx::new_allocator<std:
> :__detail::_Hash_node_base*>::allocate(unsigned long, void const*)':
> /opt/gcc-11/include/c++/11.1.0/ext/new_allocator.h:110: undefined reference
> to `std::__throw_bad_array_new_length()'
> collect2: error: ld returned 1 exit status
>
> The reproducer looks benign to me:
>
> struct Thing { int a, b, c; };
>  int main(int argc, char **argv) {
>     std::unordered_map<unsigned int, Thing *> map;
>     map[1] = new Thing;
> }
>
> I hit the linking issue when the reproducer is built with GCC11 and I
> link libzmq.so.3 that was built with GCC10. This is all happening on a
> 64-bit Linux VM and I built both compilers on the same OS (Ubuntu 16). The
> issue goes away when I rebuild the 3rd-party lib with GCC11... yet I am
> failing to understand why this is happening... Is this an oversight in
> libstdc++ that results in an ABI break?
>

Are you using 'gcc' to link, not 'g++'?

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [EXTERNAL] Re: Linking issue when mixing GCC10/GCC11 artifacts
  2021-06-29  5:32 ` Jonathan Wakely
@ 2021-06-29 15:39   ` Oleg Smolsky
  2021-06-29 15:42     ` Oleg Smolsky
  0 siblings, 1 reply; 10+ messages in thread
From: Oleg Smolsky @ 2021-06-29 15:39 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: gcc-help

I am using `g++` to link in both working and failing cases.

Oleg.

On Mon, Jun 28, 2021 at 10:32 PM Jonathan Wakely <jwakely.gcc@gmail.com>
wrote:

>
>
> On Tue, 29 Jun 2021, 05:58 Oleg Smolsky via Gcc-help, <
> gcc-help@gcc.gnu.org> wrote:
>
>> Hi, I've just hit a peculiar linking issue when using std::unordered_map,
>> C++17 and mixing some shared libs built with GCC10/11. Here is the linking
>> issue:
>>
>> test.o: In function `__gnu_cxx::new_allocator<std:
>> :__detail::_Hash_node_base*>::allocate(unsigned long, void const*)':
>> /opt/gcc-11/include/c++/11.1.0/ext/new_allocator.h:110: undefined
>> reference
>> to `std::__throw_bad_array_new_length()'
>> collect2: error: ld returned 1 exit status
>>
>> The reproducer looks benign to me:
>>
>> struct Thing { int a, b, c; };
>>  int main(int argc, char **argv) {
>>     std::unordered_map<unsigned int, Thing *> map;
>>     map[1] = new Thing;
>> }
>>
>> I hit the linking issue when the reproducer is built with GCC11 and I
>> link libzmq.so.3 that was built with GCC10. This is all happening on a
>> 64-bit Linux VM and I built both compilers on the same OS (Ubuntu 16). The
>> issue goes away when I rebuild the 3rd-party lib with GCC11... yet I am
>> failing to understand why this is happening... Is this an oversight in
>> libstdc++ that results in an ABI break?
>>
>
> Are you using 'gcc' to link, not 'g++'?
>
>
>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [EXTERNAL] Re: Linking issue when mixing GCC10/GCC11 artifacts
  2021-06-29 15:39   ` [EXTERNAL] " Oleg Smolsky
@ 2021-06-29 15:42     ` Oleg Smolsky
  2021-06-29 16:24       ` Oleg Smolsky
  0 siblings, 1 reply; 10+ messages in thread
From: Oleg Smolsky @ 2021-06-29 15:42 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: gcc-help

On Tue, Jun 29, 2021 at 8:39 AM Oleg Smolsky <osmolsky@netskope.com> 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...

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [EXTERNAL] Re: Linking issue when mixing GCC10/GCC11 artifacts
  2021-06-29 15:42     ` Oleg Smolsky
@ 2021-06-29 16:24       ` Oleg Smolsky
  2021-06-29 16:40         ` Jonathan Wakely
  0 siblings, 1 reply; 10+ messages in thread
From: Oleg Smolsky @ 2021-06-29 16:24 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: gcc-help

On Tue, Jun 29, 2021 at 8:42 AM Oleg Smolsky <osmolsky@netskope.com> wrote:

>
>
> On Tue, Jun 29, 2021 at 8:39 AM Oleg Smolsky <osmolsky@netskope.com>
> 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.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [EXTERNAL] Re: Linking issue when mixing GCC10/GCC11 artifacts
  2021-06-29 16:24       ` Oleg Smolsky
@ 2021-06-29 16:40         ` Jonathan Wakely
  2021-06-29 16:50           ` Jonathan Wakely
  2021-06-29 16:57           ` Oleg Smolsky
  0 siblings, 2 replies; 10+ messages in thread
From: Jonathan Wakely @ 2021-06-29 16:40 UTC (permalink / raw)
  To: Oleg Smolsky; +Cc: gcc-help

On Tue, 29 Jun 2021, 17:24 Oleg Smolsky, <osmolsky@netskope.com> wrote:

>
>
> On Tue, Jun 29, 2021 at 8:42 AM Oleg Smolsky <osmolsky@netskope.com>
> wrote:
>
>>
>>
>> On Tue, Jun 29, 2021 at 8:39 AM Oleg Smolsky <osmolsky@netskope.com>
>> 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.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [EXTERNAL] Re: Linking issue when mixing GCC10/GCC11 artifacts
  2021-06-29 16:40         ` Jonathan Wakely
@ 2021-06-29 16:50           ` Jonathan Wakely
  2021-06-29 16:57           ` Oleg Smolsky
  1 sibling, 0 replies; 10+ messages in thread
From: Jonathan Wakely @ 2021-06-29 16:50 UTC (permalink / raw)
  To: Oleg Smolsky; +Cc: gcc-help

On Tue, 29 Jun 2021 at 17:40, Jonathan Wakely <jwakely.gcc@gmail.com> wrote:
>
>
>
> On Tue, 29 Jun 2021, 17:24 Oleg Smolsky, <osmolsky@netskope.com> wrote:
>>
>>
>>
>> On Tue, Jun 29, 2021 at 8:42 AM Oleg Smolsky <osmolsky@netskope.com> wrote:
>>>
>>>
>>>
>>> On Tue, Jun 29, 2021 at 8:39 AM Oleg Smolsky <osmolsky@netskope.com> 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.

And if all that shows that you really are using the g++ from GCC 11
and it's finding the libstdc++.so from GCC 11, but still doesn't find
that symbol, then something weird is happening (because that symbol
should be present, and is for everybody else, because otherwise they'd
get testsuite failures complaining about it).

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [EXTERNAL] Re: Linking issue when mixing GCC10/GCC11 artifacts
  2021-06-29 16:40         ` Jonathan Wakely
  2021-06-29 16:50           ` Jonathan Wakely
@ 2021-06-29 16:57           ` Oleg Smolsky
  2021-06-29 17:22             ` Jonathan Wakely
  1 sibling, 1 reply; 10+ messages in thread
From: Oleg Smolsky @ 2021-06-29 16:57 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: gcc-help

Thank you for the hints, Jonathan!

The command is indeed g++, invoked via
automake/libtool: /opt/gcc-11/bin/g++ -g -Wall -fno-omit-frame-pointer
-gdwarf-4 -O2 -Werror -std=c++17 -Wl,-rpath -Wl,/opt/gcc-11/lib64
-Wl,-rpath -Wl,/opt/3p/lib -o ns_conn_test
libs/netsvc/test/ns_conn_test/src/cpp/NsConnTest.o  -L/opt/3p/lib
./.libs/libnsevent.a /opt/3p/lib/libzmq.so
/opt/gcc-9/lib/../lib64/libstdc++.so /opt/gcc-11/lib/../lib64/libstdc++.so
-lpthread -lrt -ldl -lm -lz -Wl,-rpath -Wl,/opt/3p/lib -Wl,-rpath
-Wl,/opt/gcc-9/lib/../lib64 -Wl,-rpath -Wl,/opt/gcc-11/lib/../lib64
-Wl,-rpath -Wl,/opt/3p/lib -Wl,-rpath -Wl,/opt/gcc-9/lib/../lib64
-Wl,-rpath -Wl,/opt/gcc-11/lib/../lib64

The problem caused by a wrong libstdc++ version that libtool stamps out. I
think it is trying to be smart and discover dependencies from the shared
libs (that were compiled a long time ago). Things link when I remove
"gcc-9" references - the new executable is linked with the new compiler and
uses the new runtime.

Thanks again for the prompt and helpful response!
Oleg.



On Tue, Jun 29, 2021 at 9:40 AM Jonathan Wakely <jwakely.gcc@gmail.com>
wrote:

>
>
> On Tue, 29 Jun 2021, 17:24 Oleg Smolsky, <osmolsky@netskope.com> wrote:
>
>>
>>
>> On Tue, Jun 29, 2021 at 8:42 AM Oleg Smolsky <osmolsky@netskope.com>
>> wrote:
>>
>>>
>>>
>>> On Tue, Jun 29, 2021 at 8:39 AM Oleg Smolsky <osmolsky@netskope.com>
>>> 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.
>
>
>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [EXTERNAL] Re: Linking issue when mixing GCC10/GCC11 artifacts
  2021-06-29 16:57           ` Oleg Smolsky
@ 2021-06-29 17:22             ` Jonathan Wakely
  2021-06-29 23:04               ` Oleg Smolsky
  0 siblings, 1 reply; 10+ messages in thread
From: Jonathan Wakely @ 2021-06-29 17:22 UTC (permalink / raw)
  To: Oleg Smolsky; +Cc: gcc-help

On Tue, 29 Jun 2021, 17:57 Oleg Smolsky, <osmolsky@netskope.com> wrote:

> Thank you for the hints, Jonathan!
>
> The command is indeed g++, invoked via
> automake/libtool: /opt/gcc-11/bin/g++ -g -Wall -fno-omit-frame-pointer
> -gdwarf-4 -O2 -Werror -std=c++17 -Wl,-rpath -Wl,/opt/gcc-11/lib64
> -Wl,-rpath -Wl,/opt/3p/lib -o ns_conn_test
> libs/netsvc/test/ns_conn_test/src/cpp/NsConnTest.o  -L/opt/3p/lib
> ./.libs/libnsevent.a /opt/3p/lib/libzmq.so
> /opt/gcc-9/lib/../lib64/libstdc++.so /opt/gcc-11/lib/../lib64/libstdc++.so
> -lpthread -lrt -ldl -lm -lz -Wl,-rpath -Wl,/opt/3p/lib -Wl,-rpath
> -Wl,/opt/gcc-9/lib/../lib64 -Wl,-rpath -Wl,/opt/gcc-11/lib/../lib64
> -Wl,-rpath -Wl,/opt/3p/lib -Wl,-rpath -Wl,/opt/gcc-9/lib/../lib64
> -Wl,-rpath -Wl,/opt/gcc-11/lib/../lib64
>

Yikes! Yeah, libtool has really created a mess here.


>
> The problem caused by a wrong libstdc++ version that libtool stamps out. I
> think it is trying to be smart and discover dependencies from the shared
> libs (that were compiled a long time ago). Things link when I remove
> "gcc-9" references - the new executable is linked with the new compiler and
> uses the new runtime.
>
> Thanks again for the prompt and helpful response!
> Oleg.
>
>
>
> On Tue, Jun 29, 2021 at 9:40 AM Jonathan Wakely <jwakely.gcc@gmail.com>
> wrote:
>
>>
>>
>> On Tue, 29 Jun 2021, 17:24 Oleg Smolsky, <osmolsky@netskope.com> wrote:
>>
>>>
>>>
>>> On Tue, Jun 29, 2021 at 8:42 AM Oleg Smolsky <osmolsky@netskope.com>
>>> wrote:
>>>
>>>>
>>>>
>>>> On Tue, Jun 29, 2021 at 8:39 AM Oleg Smolsky <osmolsky@netskope.com>
>>>> 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.
>>
>>
>>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [EXTERNAL] Re: Linking issue when mixing GCC10/GCC11 artifacts
  2021-06-29 17:22             ` Jonathan Wakely
@ 2021-06-29 23:04               ` Oleg Smolsky
  0 siblings, 0 replies; 10+ messages in thread
From: Oleg Smolsky @ 2021-06-29 23:04 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: gcc-help

On Tue, Jun 29, 2021 at 10:23 AM Jonathan Wakely <jwakely.gcc@gmail.com>
wrote:

>
>
> On Tue, 29 Jun 2021, 17:57 Oleg Smolsky, <osmolsky@netskope.com> wrote:
>
>> Thank you for the hints, Jonathan!
>>
>> The command is indeed g++, invoked via
>> automake/libtool: /opt/gcc-11/bin/g++ -g -Wall -fno-omit-frame-pointer
>> -gdwarf-4 -O2 -Werror -std=c++17 -Wl,-rpath -Wl,/opt/gcc-11/lib64
>> -Wl,-rpath -Wl,/opt/3p/lib -o ns_conn_test
>> libs/netsvc/test/ns_conn_test/src/cpp/NsConnTest.o  -L/opt/3p/lib
>> ./.libs/libnsevent.a /opt/3p/lib/libzmq.so
>> /opt/gcc-9/lib/../lib64/libstdc++.so /opt/gcc-11/lib/../lib64/libstdc++.so
>> -lpthread -lrt -ldl -lm -lz -Wl,-rpath -Wl,/opt/3p/lib -Wl,-rpath
>> -Wl,/opt/gcc-9/lib/../lib64 -Wl,-rpath -Wl,/opt/gcc-11/lib/../lib64
>> -Wl,-rpath -Wl,/opt/3p/lib -Wl,-rpath -Wl,/opt/gcc-9/lib/../lib64
>> -Wl,-rpath -Wl,/opt/gcc-11/lib/../lib64
>>
>
> Yikes! Yeah, libtool has really created a mess here.
>

Yes! For the record, the issue was caused by a funky transformation that
the automake/libtool build system does when it sees `-lfoo` and finds a `
libfoo.la` somewhere in the lib path. The ".la" file is generated by every
automake/libtool-based build system that produces libraries and is
installed with `make install` by default.

Hopefully this note will save someone a bit of time down the road. The
debugging steps are:
 - `make your-target V=1` to see the compiler options for the linking step
 - check whether your own `-lfoo` is magically converted into
`...../libfoo.so ..../libstdc++.so`

This happens when using GCC installed into a non-standard path (as it
forces users to bake libstdc++ path into ELF files with the
`-Wl,--rpath,....` option) and mixing compiler versions.

Oleg.


>

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2021-06-29 23:04 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-29  4:55 Linking issue when mixing GCC10/GCC11 artifacts Oleg Smolsky
2021-06-29  5:32 ` Jonathan Wakely
2021-06-29 15:39   ` [EXTERNAL] " Oleg Smolsky
2021-06-29 15:42     ` Oleg Smolsky
2021-06-29 16:24       ` Oleg Smolsky
2021-06-29 16:40         ` Jonathan Wakely
2021-06-29 16:50           ` Jonathan Wakely
2021-06-29 16:57           ` Oleg Smolsky
2021-06-29 17:22             ` Jonathan Wakely
2021-06-29 23:04               ` Oleg Smolsky

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).