question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Possibly wrong link order / devtoolset-8 libstdc++ unknown symbols

See original GitHub issue

You are probably not going to like this one that much.

It seems that bazel + binutils + gcc + redhats devtoolset-8 gets angry regarding -lstdc++, this appears to be related to https://bugzilla.redhat.com/show_bug.cgi?id=1570853

Recording of the bug

The following is a (long) recording of the bug, and workaround, the following documents it outright

asciicast

Bazel issues with devtoolset-8 regarding libstdc++

It appears that bazel is adding -lstdc++ into the linker arguments early in the command line for gcc. This freaks out oddball environments (such as the one provided by the software collections library).

SCL from RedHat provides a linker script in place of libstdc++ which does some trickery to fake out having an old libstdc++ installed on the system, but needing newer symbols for newer C++ features, versions and ABIs. This is seemingly done to allow for cross ABI compatibility

Reproducing

I have tested this in the environment we must compile for at $DAYJOB, I have not tested using stock RHEL or Centos but I suspect it might be an issue. It could also be a more general problem with link ordering.

Any bazel build using C++ will break including bootstrapping bazel itself

Setup a test env with docker

The following should give a test env that can reproduce the issue

docker run -it oraclelinux:slim-6

# Inside this env
yum install -y yum-security
yum updateinfo -y --verbose

yum-config-manager --enable -y ol6_latest
yum-config-manager --enable -y ol6_software_collections
yum updateinfo -y --verbose
yum install -y scl-utils

# Install some basics
yum install which curl wget unzip zip bzip2 patch xz

# Grab a compiler
yum install -y devtoolset-8-gcc devtoolset-8-gcc-c++ devtoolset-8-binutils devtoolset-8-toolchain

# Grab a python
yum install -y rh-python36-python

# Grab a jvm
rpm --import http://repos.azulsystems.com/RPM-GPG-KEY-azulsystems
curl -o /etc/yum.repos.d/zulu.repo http://repos.azulsystems.com/rhel/zulu.repo
yum install -y zulu-8

# Setup a environment faker to force the use of devtoolkit-8 as a compiler
cat > /opt/scl_enable <<EOF
#!/bin/bash
unset BASH_ENV PROMPT_COMMAND ENV
source scl_source enable devtoolset-8
source scl_source enable python27
EOF

chmod 755 /opt/scl_enable

# Grab bazel
mkdir /root/bazel_bootstrap
cd /root/bazel_bootstrap
wget https://github.com/bazelbuild/bazel/releases/download/1.2.1/bazel-1.2.1-dist.zip
unzip bazel-1.2.1-dist.zip

# The magical env is to force into SCL / devtoolkit
# It can be sourced, but that has historically proven to be unrealiable in our CI env
BASH_ENV=/opt/scl_enable ENV=/opt/scl_enable PROMPT_COMMAND=". /opt/scl_enable" ./compile.sh

… After a while bazel will fail to compile with some C++ linker error, normally complaining about some undefined symbol. The undef symbol will be something deep in libstdc++

What I think causes this

Looking at a failed link, we find that bazel produces linker args something like so

-o bazel-out/host/bin/external/com_google_protobuf/protoc
-Wl,-S
-fuse-ld=gold
-Wl,-no-as-needed 
-Wl,-z,relro,-z,now
-B/opt/rh/devtoolset-8/root/usr/bin
-pass-exit-codes
-lstdc++
-lm
-Wl,--gc-sections
bazel-out/host/bin/external/com_google_protobuf/_objs/protoc/main.o                                                                     -Wl,--start-lib
bazel-out/host/bin/external/com_google_protobuf/_objs/protoc_lib/code_generator.o                                                       
SNIP SNIP %<  ...
-Wl,--end-lib
-lpthread
-lm
-lpthread
-lm
-lpthread
-lm

Looking at the file libstdc++.so under devtoolkit-8 it looks like so

/* GNU ld script Use the shared library, but some functions are only in 
the static library, so try that secondarily.  */                       

OUTPUT_FORMAT(elf64-x86-64)
INPUT ( /usr/lib64/libstdc++.so.6 -lstdc++_nonshared )

Which is trickery to, as mentioned above, use ABI hacks, this confuses ld and I think removes the special handling for libstdc++

Moving libstdc++ to the bottom like so

-o bazel-out/host/bin/external/com_google_protobuf/protoc                                                                                  -Wl,-S
-fuse-ld=gold
-Wl,-no-as-needed
-Wl,-z,relro,-z,now
-B/opt/rh/devtoolset-8/root/usr/bin
-pass-exit-codes
-Wl,--gc-sections
bazel-out/host/bin/external/com_google_protobuf/_objs/protoc/main.o
-Wl,--start-lib
bazel-out/host/bin/external/com_google_protobuf/_objs/protoc_lib/code_generator.o
SNIP SNIP %<  ...
-Wl,--end-lib
-lpthread
-lm
-lpthread
-lm
-lpthread
-lm
-lstdc++
-lm

Allows for linking

Workaround

A workaround we have found is to export the following

BAZEL_LINKOPTS=-static-libstdc++ BAZEL_LINKLIBS=-l%:libstdc++.a

… technically this statically links libstdc++ and is probably not what some people want

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:9 (3 by maintainers)

github_iconTop GitHub Comments

5reactions
nukescommented, Jun 23, 2020

solve this problem with: BAZEL_LINKOPTS=“” BAZEL_LINKLIBS=“-lstdc++” bazel build …

1reaction
stellaraccidentcommented, Jan 6, 2021

Another egregious hack memorialized: https://github.com/stellaraccident/manylinux-bazel

Read more comments on GitHub >

github_iconTop Results From Across the Web

Bug #1824721 “g++-8 in disco is broken with libstdc++6 from ...
The link order does seem to be significant as you suggested. However, both the linker and run-time linker succeed without error. The failure...
Read more >
The linking of libstdc++ (again, sorry) - Google Groups
The idea is to not expose the symbols of the statically linked libstdc++ - thus, ... to earlier versions - am I potentially...
Read more >
CentOS: Using GCC 4.7 from devtoolset results in linking ...
I already tried to set LD_LIBRARY_PATH and pointing to the devtoolset directory, but the libstdc++ was still set to the old location. Also...
Read more >
User Guide Red Hat Developer Toolset 10
In Red Hat Developer Toolset, libraries are linked using linker scripts which might specify some symbols through static archives. This is required to...
Read more >
(RHSA-2021:4669) Moderate: devtoolset-11-gcc security update
The devtoolset-11-gcc packages provide the Red Hat Developer ... in gcc in order to facilitate detection of BiDi Unicode characters: This ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found