Bug 1519073 - Cannot link shared object that uses std::bitset with code that does bool(std::basic_ios). hidden symbol '_ZNSt12__sso_stringC1EPKcm' is not defined.
Summary: Cannot link shared object that uses std::bitset with code that does bool(std:...
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Red Hat Developer Toolset
Classification: Red Hat
Component: gcc
Version: DTS 7.0 RHEL 7
Hardware: Unspecified
OS: Unspecified
unspecified
unspecified
Target Milestone: alpha
: 7.1
Assignee: Marek Polacek
QA Contact: Michael Petlan
Vladimír Slávik
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2017-11-30 03:36 UTC by John Steele Scott
Modified: 2021-06-10 13:45 UTC (History)
14 users (show)

Fixed In Version: devtoolset-7-gcc-7.2.1-6.el6
Doc Type: Bug Fix
Doc Text:
Previously, some symbols in the "libstdc++_nonshared.a" static library file used incorrect visibility. As a consequence, linking some C++ programs failed. This bug has been fixed and no longer occurs.
Clone Of:
Environment:
Last Closed: 2018-05-03 05:13:47 UTC
Target Upstream Version:
Embargoed:


Attachments (Terms of Use)


Links
System ID Private Priority Status Summary Last Updated
Red Hat Product Errata RHBA-2018:1293 0 None None None 2018-05-03 05:14:38 UTC

Description John Steele Scott 2017-11-30 03:36:07 UTC
Description of problem:

Linking a complex project with many shared objects failed with:

/opt/rh/devtoolset-7/root/usr/libexec/gcc/x86_64-redhat-linux/7/ld.gold: error: hidden symbol '_ZNSt12__sso_stringC1EPKcm' is not defined locally
/opt/rh/devtoolset-7/root/usr/libexec/gcc/x86_64-redhat-linux/7/ld.gold: error: hidden symbol '_ZNSt12__sso_stringC1EPKcm' is not defined locally

I have boiled this down to a small reproduction.


Version-Release number of selected component (if applicable):

devtoolset-7-gcc-c++-7.2.1-1.el7.x86_64.rpm


How reproducible:

Every time.

Steps to Reproduce:

Run this reproduction script in a devtoolset-7 shell:

---------
#!/bin/bash

cat > bitset-user.cpp <<EOF
#include <bitset>

static std::bitset<1> bs;

bool test_bit (size_t pos) 
{ 
  /* With DTS 7 this pulls in libstdc++_nonshared.a(sso_string.o), which
   * gives the sso string stuff default visibility.
   */
  return bs.test(pos); 
}
EOF

cat > main.cpp <<EOF
#include <bitset>
#include <iostream>

bool test_bit (size_t pos);

int main ()
{
  test_bit(0);

  /* With DTS 7 this pulls in libstdc++_nonshared.a(system_error48.o), which
   * gives the sso string functions hidden visibility, overriding the default
   * visibility declared in sso_string.o.
   */
  return bool(std::cout);
}
EOF

GOLD="-fuse-ld=gold"
#TRACE="-Wl,--trace"
g++ $GOLD $TRACE -std=c++14 -shared -fPIC -o bitset-user.so bitset-user.cpp 
echo
g++ $GOLD $TRACE -std=c++14 main.cpp bitset-user.so
---------

Actual results:

When using the gold linker it fails like:

/opt/rh/devtoolset-7/root/usr/libexec/gcc/x86_64-redhat-linux/7/ld.gold: error: hidden symbol '_ZNSt12__sso_stringC1EPKcm' is not defined locally
/opt/rh/devtoolset-7/root/usr/libexec/gcc/x86_64-redhat-linux/7/ld.gold: error: hidden symbol '_ZNSt12__sso_stringC1EPKcm' is not defined locally

When using the binutils linker it fails like:

/opt/rh/devtoolset-7/root/usr/lib/gcc/x86_64-redhat-linux/7/libstdc++_nonshared.a(cow-stdexcept.o): In function `std::__sso_string::__sso_string(std::string const&)':
(.text._ZNSt12__sso_stringC2ERKSs+0x8): undefined reference to `std::__sso_string::__sso_string(char const*, unsigned long)'
/opt/rh/devtoolset-7/root/usr/lib/gcc/x86_64-redhat-linux/7/libstdc++_nonshared.a(cow-stdexcept.o): In function `std::_V2::error_category::_M_message(int) const':
(.text._ZNKSt3_V214error_category10_M_messageEi+0x30): undefined reference to `std::__sso_string::__sso_string(char const*, unsigned long)'
/opt/rh/devtoolset-7/root/usr/libexec/gcc/x86_64-redhat-linux/7/ld: a.out: hidden symbol `_ZNSt12__sso_stringC2ERKS_' isn't defined
/opt/rh/devtoolset-7/root/usr/libexec/gcc/x86_64-redhat-linux/7/ld: final link failed: Bad value
collect2: error: ld returned 1 exit status


Expected results:

Should link with no errors. Works fine with DTS 4 and DTS 6.


Additional info:

Root cause seems to be that the sso string functions are declared to have default visiiblity in libstdc++_nonshared.a(sso_string.o) [and also libstdc++_nonshared.a(cow-stdexcept.o)] but hidden visibility in libstdc++_nonshared.a(system_error48.o). In DTS 6 there was a similar inconsistency, but the definition was "hidden" in system_error48.o (not sso_string.o as in DTS 7) which trumped the "default" declaration in cow-stdexcept.o every time. So despite the inconsistency, nothing broke.

Comment 2 Marek Polacek 2017-12-05 21:46:53 UTC
In DTS 7.0, _ZNSt12__sso_stringC1EPKcm is defined in libstdc++_nonshared.a(sso_string.o), where it's GLOBAL DEFAULT.  It is referenced in libstdc++_nonshared.a(cow-stdexcept.o) where it's GLOBAL DEFAULT.  The symbol is also in libstdc++_nonshared.a(system_error48.o) where due to
asm (".hidden _ZNSt12__sso_stringC1EPKcm");
it's GLOBAL HIDDEN.

In the testcase, when creating bitset-user.so libstdc++_nonshared.a(sso_string.o) is pulled in, so the resulting bitset-user.so has GLOBAL DEFAULT _ZNSt12__sso_stringC1EPKcm.  But then when linking "main.cpp bitset-user.so" these additional .o are pulled in:
(/opt/rh/devtoolset-7/root/usr/lib/gcc/x86_64-redhat-linux/7/libstdc++_nonshared.a)ios-inst.o
(/opt/rh/devtoolset-7/root/usr/lib/gcc/x86_64-redhat-linux/7/libstdc++_nonshared.a)ios.o
(/opt/rh/devtoolset-7/root/usr/lib/gcc/x86_64-redhat-linux/7/libstdc++_nonshared.a)cxx11-ios_failure.o
(/opt/rh/devtoolset-7/root/usr/lib/gcc/x86_64-redhat-linux/7/libstdc++_nonshared.a)cxx11-stdexcept.o
(/opt/rh/devtoolset-7/root/usr/lib/gcc/x86_64-redhat-linux/7/libstdc++_nonshared.a)cow-stdexcept.o
(/opt/rh/devtoolset-7/root/usr/lib/gcc/x86_64-redhat-linux/7/libstdc++_nonshared.a)system_error48.o

But pulling in system_error48.o with the .hidden directive hides the _ZNSt12__sso_stringC1EPKcm symbol.

In DTS 6.1 this does not happen because _ZNSt12__sso_stringC1EPKcm is defined in system_error48.o, where it's GLOBAL HIDDEN.  It's only referenced in cow-stdexcept.o.  When creating bitset-user.so, both cow-stdexcept.o and system_error48.o are pulled in.  The resulting bitset-user.so has LOCAL DEFAULT _ZNSt12__sso_stringC1EPKcm.  But when linking "main.cpp bitset-user.so", nothing that references that symbol is pulled in, so all is well.

Comment 3 Marek Polacek 2017-12-05 21:48:55 UTC
I've distilled a C testcase:

$ cat bar.c
// system_error48.o.
extern void foo (void);
void
baz (void)
{
  foo ();
}
asm (".hidden foo");

$ cat foo.c
// sso_string.o
void
foo (void)
{
  __builtin_puts (__func__);
}

$ gcc -shared -fPIC -o libfoo.so foo.c
$ gcc -c bar.c --save-temps
$ ar crs libbar.a bar.o
$ gcc main.c libfoo.so libbar.a -o r && LD_LIBRARY_PATH=. ./r

Comment 4 Marek Polacek 2017-12-05 21:57:33 UTC
Since _ZNSt12__sso_stringC1EPKcm is no longer defined in system_error48.o
asm (".hidden _ZNSt12__sso_stringC1EPKcm");
et al might be obsolete now?

Comment 11 Marek Polacek 2017-12-12 10:50:22 UTC
Patch committed.

Comment 13 zhengzhejun 2018-01-08 05:03:01 UTC
I encounter the similar error in the version 6.3.1-3.1.el7. Would it be fixed too ?

Comment 14 zhengzhejun 2018-01-08 05:12:30 UTC
I encounter the similar problem in the version 7.2.1-1.el7.sc1. Would it be fixed too?

Comment 15 Jiangdong Sun 2018-03-06 11:21:57 UTC
How to get devtoolset-7-gcc-7.2.1-6.el6? on RHN the lastest version is still devtoolset-7-gcc-7.2.1-1.el7.x86_64.rpm. Thanks!

Comment 16 Jiangdong Sun 2018-03-07 05:57:51 UTC
@Marek Could you please attach the patch here? Thanks!

Comment 17 Matt Newsome 2018-03-08 22:17:02 UTC
(In reply to Jiangdong Sun from comment #16)
> @Marek Could you please attach the patch here? Thanks!

This fix is currently scheduled for the next release of Red Hat Developer Toolset, v7.1, which will be announced when a public beta release is made available to Red Hat Enterprise Linux subscribers in the coming weeks.

Red Hat engineering has concluded that earlier major releases of Red Hat Developer Toolset are not suitable to be patched for this issue and our recommendation to customers is to migrate projects to Red Hat Developer Toolset 7.1 where possible, on its release.

We advise against customers patching and building their own binaries from patches as this produces unsupported toolchain binaries due to a number of differences in the build environment and dependencies.

Comment 18 Jiangdong Sun 2018-03-15 09:26:22 UTC
@Matt Thanks for your reply. Hope the updated packages can be distributed early.

Comment 20 Michael Petlan 2018-04-25 16:56:04 UTC
Tested with devtoolset-7-gcc-7.3.1-5.4, both linkers (where gold is available). Successfully reproduced with older DTS-7.0's detvoolset-7-gcc.
VERIFIED.

Comment 23 errata-xmlrpc 2018-05-03 05:13:47 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory, and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://access.redhat.com/errata/RHBA-2018:1293


Note You need to log in before you can comment on or make changes to this bug.