46

I have installed the Tensorflow bindings with python successfully. But when I try to import Tensorflow, I get the follwoing error.

ImportError: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.17' not found (required by /usr/local/lib/python2.7/dist-packages/tensorflow/python/_pywrap_tensorflow.so)

I have tried to update GLIBC_2.15 to 2.17, but no luck.

Trooper Z
  • 1,617
  • 14
  • 31
Tanvir
  • 875
  • 3
  • 11
  • 19

14 Answers14

23

I've just managed to install tensorflow 0.12rc0 on CentOS 6.5 with glibc 2.12, without having root privileges. Simply installing tensorflow binary via pip was giving me an error, related to GLIBC version as well.

Basically, you have 4 options how to deal with this (each with some advantages and disadvantages):

Option 1 - Upgrade your system GLIBC globally.

This is, probably, the best option, if your system supports this, you have root privileges, and you are confident that this upgrade won't break anything for some weird reason. Ultimately, this goes up to upgrading the whole Linux distribution. Here's a nice short list of default GLIBC versions on popular distributions.

Option 2 - Add second GLIBC to your system

Compile or download binary. The most simple&straightforward option. Especially if you only need to run few simple scripts.

  • It is possible to have multiple versions of glibc on the same system, but one should do this with a great care.
  • You won't destroy your system, if all your changes would be limited to a virtual environment.
  • Many programs, installed/compiled before might be relying on old GLIBC, would just crash in your new environment (e.g. your python IDE). Including most basic bash commands, like "lc", "cd", etc.
  • Other side-effects like significant memory leaks are also possible.
  • Thus, it's a very bad idea to add new GLIBC to your normal environment, e.g. via .bashrc.
  • On the other hand, if you need some specific tool in your new virtual environment, you may recompile it, linking against new GLIBC. So, that it would work OK in your new enviroment.
  • However, personally, I quickly gave up recompiling everything I need in a new environment (without root and a package manager).
  • A slightly different approach is officially offered by GLIBC developers, for testing new GLIBC builds.

Option 3 - Patch tensorflow

This may work for TF 0.6.0, but you would probably have to start again from scratch, when each new tensorflow version is released. E.g. here's a fix for 0.9.0.

Option 4 - Compile tensorflow from source

If you re-compile it from source and link against your existing GLIBC, newer GLIBC would be no longer needed. Somehow, this option was not mentioned in any answer here yet. Imho, this is the best option, both "in general", and "specifically for tensorflow".

  • This works OK with r0.11 and would probably work for years, but theoretically, it might break in some newer tensorflow version, if they would decide to actually use some new GLIBC functionality, not present in older versions.
  • To be honest, building tensorflow from source is not straightforward, especially on outdated systems.

A quick summary of "building tensorflow on outdated system":

Although the official guide provides a "installing from sources" section, there are few tricks you need to do to build it on an outdated system. Here I assume, that you do not have root privileges (if you do - you probably would be able to install the same pre-requestities with a package manager, rather them manually building them from source).

I found two well-documented success stories: #1, #2 and a number of useful posts on the official github (mostly about a set of libraries to link inside the binary): #1, #2, #3, #4. I had to combine tricks, described there to successfully compile TF in my case.

  1. First of all, check your gcc --version, and verify that it supports c++11. Mine was 4.4.7, so it won't work. I've downloaded gcc-4.9.4 source code, and compiled it. This step is pretty straightforward, but the compilation itself may take few hours. As a workaround for an issue in bazel, I've compiled gcc with hardcoded paths to as,ld and nm. However, you may try another workarounds: (1, 2).

    #!/bin/sh
    
    unset LIBRARY_PATH CPATH C_INCLUDE_PATH 
    unset PKG_CONFIG_PATH CPLUS_INCLUDE_PATH INCLUDE LD_LIBRARY_PATH
    
    cd gcc-4.9.4
    ./contrib/download_prerequisites
    
    mkdir objdir
    cd objdir
    
    
    # I've added --disable-multilib to fix the following error:
    # /usr/bin/ld: crt1.o: No such file: No such file or directory
    # collect2: ld returned 1 exit status
    # configure: error: I suspect your system does not have 32-bit 
    # developement libraries (libc and headers). If you have them,
    # rerun configure with --enable-multilib. If you do not have them, 
    # and want to build a 64-bit-only compiler, rerun configure 
    # with --disable-multilib.           
    
    ../configure --prefix=$HOME/opt/gcc-4.9.4 \
                 --disable-multilib \
                 --disable-nls \
                 --enable-languages=c,c++ \
                 --with-ld=/usr/bin/ld \
                 --with-nm=/usr/bin/nm \
                 --with-as=/usr/bin/as
    
    make        
    make install
    
  2. Check your java --version. Bazel requires JDK 8, install it if necessary. (They still provide some jdk7 related downloads, for bazel-0.4.1 but it looks like they consider it deprecated)

  3. I've created a separate use_gcc_4.9.4.sh file, with necessary environment variables. I use source ./use_gcc_4.9.4.sh when I need to so something related to this newer compiler.

    #!/bin/sh
    this=$HOME/opt/gcc-4.9.4
    export PATH=$this/bin:$PATH
    export CPATH=$this/include:$CPATH
    export LIBRARY_PATH=$this/lib:$LIBRARY_PATH
    export LIBRARY_PATH=$this/lib64:$LIBRARY_PATH
    export LD_LIBRARY_PATH=$this/lib:$LD_LIBRARY_PATH
    export LD_LIBRARY_PATH=$this/lib64:$LD_LIBRARY_PATH
    
  4. The current bazel binary (0.4.1) requires GLIBC 2.14, so we have to compile bazel from source as well (with our new gcc). Works OK, unless you are only allowed to run a very limited number of threads on the target machine. (This post describes some additional workarounds, but in my case they were not needed, maybe due to recent updates in bazel code.)

  5. Obtain tensorflow source code git clone https://github.com/tensorflow/tensorflow, and install prerequisites you need (CUDA,cuDNN,python, etc). See official guide.

  6. If you're not using default system gcc (e.g. if you had to compile newer gcc, like discussed above), add the following linker flags to tensorflow/third_party/gpus/crosstool/CROSSTOOL.tpl, line 59:

    linker_flag: "-L/home/username/localinst/opt/gcc-4.9.4/lib64"
    linker_flag: "-Wl,-rpath,/home/username/localinst/opt/gcc-4.9.4/lib64"
    

    Without this step, you would likely run into error messages like this:

    # ERROR: /home/username/localdistr/src/tensorflow/tensorflow/tensorflow/core/debug/BUILD:33:1: null failed: protoc failed: error executing command bazel-out/host/bin/external/protobuf/protoc '--cpp_out=bazel-out/local_linux-py3-opt/genfiles/' '--plugin=protoc-gen-grpc=bazel-out/host/bin/external/grpc/grpc_cpp_plugin' ... (remaining 8 argument(s) skipped): com.google.devtools.build.lib.shell.BadExitStatusException: Process exited with status 1.
    # bazel-out/host/bin/external/protobuf/protoc: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by bazel-out/host/bin/external/protobuf/protoc)
    # bazel-out/host/bin/external/protobuf/protoc: /usr/lib64/libstdc++.so.6: version `CXXABI_1.3.8' not found (required by bazel-out/host/bin/external/protobuf/protoc)
    # bazel-out/host/bin/external/protobuf/protoc: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.18' not found (required by bazel-out/host/bin/external/protobuf/protoc)
    
  7. Finally, to avoid GLIBC dependencies, we have to statically link some libraries, by adding the -lrt linker flag (maybe -lm as well). I found multiple posts, suggesting to add this in a different manner:

    Without -lrt I ran into GLIBC-version-specific error again, trying to import tensorflow:

    # ImportError: /lib64/libc.so.6: version `GLIBC_2.14' not found (required by /home/username/anaconda3/envs/myenvname/lib/python3.5/site-packages/tensorflow/python/_pywrap_tensorflow.so)
    

    Without -lm you may run into this (for me, it turned out to be not necessary).

  8. Run the build process.

    source ./use_gcc_4.9.4.sh
    ./configure
    bazel build -c opt --config=cuda //tensorflow/tools/pip_package:build_pip_package
    bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg
    pip install --upgrade /tmp/tensorflow_pkg/tensorflow-0.12.0rc0-cp35-cp35m-linux_x86_64.whl
  1. Try to run the following simple python script to test if the most basic stuff is functioning:

    import tensorflow as tf
    hello = tf.constant('Hello, TensorFlow!')
    sess = tf.Session()
    print(sess.run(hello))
    
    a = tf.constant(10)
    b = tf.constant(32)
    print(sess.run(a + b))
    
Community
  • 1
  • 1
Igor
  • 1,359
  • 19
  • 34
  • got this `configure: error: cannot execute: usr/bin/as: check --with-as or env. var. DEFAULT_ASSEMBLER make[2]: *** [configure-stage1-gcc] Error 1 make[2]: Leaving directory '/mnt/home/xx/download/gcc-4.9.4/objdir' make[1]: *** [stage1-bubble] Error 2 make[1]: Leaving directory '/mnt/home/xx/download/gcc-4.9.4/objdir' make: *** [all] Error 2 ` when I configure gcc – Belter Apr 19 '17 at 05:44
  • @Belter, that's probably something OS-dependent. Are you sure your "as" is working properly? Maybe you should start from typing "which as" and trying to execute it. Anyway, this issue is more related to building gcc than to building tensorflow, so it's hardly related to this topic. – Igor Apr 19 '17 at 10:22
  • I build by `bazel build --config=opt //tensorflow/tools/pip_package:build_pip_package`, like here[https://www.tensorflow.org/install/install_sources] suggest, without gup. And I added `linker_flag: "-L/home/username/localinst/opt/gcc-4.9.4/lib64" linker_flag: "-Wl,-rpath,/home/username/localinst/opt/gcc-4.9.4/lib64"` to `tensorflow/third_party/gpus/crosstool/CROSSTOOL.tpl`, still got error `...'GLIBCXX_3.4.20' not found..., ...'CXXABI_1.3.8' not found..., ...'GLIBCXX_3.4.18' not found...` – Belter Apr 19 '17 at 13:26
  • For your second option, should [installation of glibc with conda](https://anaconda.org/search?q=glibc) work? I [tried this](https://stackoverflow.com/a/54628478/974555), but it did not make it work (`glibc` from `nlesc` or `mgckind` keeps the same behaviour, `glibc` from `asmeurer` gives `python: error while loading shared libraries: __vdso_time: invalid mode for dlopen(): Invalid argument`) – gerrit Feb 11 '19 at 10:53
  • @gerrit, I've got no experience with those packages. Theoretically - it should work. In practice - it depends. Check your path env vars first, make sure you're not picking any libs from the outside of the venv, like [this](https://stackoverflow.com/a/13675167/1032586). There's a slight chance that [LD_DEBUG](http://www.bnikolic.co.uk/blog/linux-ld-debug.html) would help. – Igor Feb 12 '19 at 18:13
  • @Igor Finally, [I did get it to work](https://stackoverflow.com/a/54628478/974555) (for numba, with which I experienced the same symptoms as described here with TensorFlow) but only if I install some packages with conda and some with pip and in a particular order... – gerrit Feb 13 '19 at 08:41
18

I tried BR_User solution and still had an annoying:

ImportError: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.14' not found

I am on CentOS 6.7, it also lacks an updated c++ standard lib, so to build on BR_User solution I extracted the correct libstdc++ package, however I found no need for the virtual environment.

Supposing you have already installed tensorflow, it gives:

mkdir ~/my_libc_env
cd ~/my_libc_env
wget http://launchpadlibrarian.net/137699828/libc6_2.17-0ubuntu5_amd64.deb
wget http://launchpadlibrarian.net/137699829/libc6-dev_2.17-0ubuntu5_amd64.deb
wget ftp.riken.jp/Linux/scientific/7.0/x86_64/os/Packages/libstdc++-4.8.2-16.el7.x86_64.rpm
ar p libc6_2.17-0ubuntu5_amd64.deb data.tar.gz | tar zx
ar p libc6-dev_2.17-0ubuntu5_amd64.deb data.tar.gz | tar zx
rpm2cpio libstdc++-4.8.2-7mgc30.x86_64.rpm| cpio -idmv

and then run python with:

LD_LIBRARY_PATH="$HOME/my_libc_env/lib/x86_64-linux-gnu/:$HOME/my_libc_env/usr/lib64/" $HOME/my_libc_env/lib/x86_64-linux-gnu/ld-2.17.so `which python`

If it doesn't work, I have another solution, but you won't like it.

Aviram Fireberger
  • 3,910
  • 5
  • 50
  • 69
Théo T
  • 3,270
  • 5
  • 20
  • 22
  • 1
    For me it worked only if I added `$LD_LIBRARY_PATH:` on the beginning. – kotrfa Feb 09 '16 at 11:31
  • Yes that's normal, you can make yourself an `alias` in your `.bashrc` if you don't want to type everything everytime – Théo T Feb 09 '16 at 14:14
  • Works on RHEL 6.5. Wow. PFM. – John McGehee Aug 04 '16 at 23:37
  • 5
    After running `import tensorflow` am facing the following error: `error while loading shared libraries: __vdso_time: invalid mode for dlopen(): Invalid argument` [Issue #2105](https://github.com/tensorflow/tensorflow/issues/2105) – CᴴᴀZ Sep 06 '16 at 16:48
  • now `wget ftp://rpmfind.net/linux/...` fails with `No such directory “linux/sourceforge/m/ma/magicspecs/apt/3.0/x86_64/RPMS.lib”`. Any idea on alternatives to get this package? – Yuval Atzmon Mar 25 '17 at 16:31
  • 4
    The following now (Mar 2017) fails: wget ftp://rpmfind.net/linux/sourceforge/m/ma/magicspecs/apt/3.0/x86_64/RPMS.lib/libstdc++-4.8.2-7mgc30.x86_64.rpm Instead you can try: wget ftp://195.220.108.108/linux/mageia/distrib/4/x86_64/media/core/updates/libstdc++6-4.8.2-3.2.mga4.x86_64.rpm and rpm2cpio libstdc++6-4.8.2-3.2.mga4.x86_64.rpm | cpio -idmv For future reference (if it will break again), this alternative link was found under: https://www.rpmfind.net/linux/rpm2html/search.php?query=libstdc%2B%2B.so.6(GLIBCXX_3.4.16)(64bit) – Yuval Atzmon Mar 26 '17 at 15:07
  • updated link: http://ftp.riken.jp/Linux/scientific/7.0/x86_64/os/Packages/libstdc++-4.8.2-16.el7.x86_64.rpm – christopherlovell Jun 20 '17 at 21:16
  • I could worship you. – jayant Dec 17 '17 at 18:35
  • It worked for me and I guess this is the best solution overall since you won't need to recompile TF. But I still get an annoying "bin/sh: error while loading shared libraries: __vdso_time: invalid mode for dlopen(): Invalid argument" though I could import tensorflow. Any idea why? – user2189731 May 23 '19 at 09:01
  • Any chance it will be working on tcsh? I can't add LD_LIBRARY_PATH before command. – user2189731 May 23 '19 at 09:02
  • I get `Segmentation fault (core dumped)` – Exploring Apr 14 '20 at 06:04
17

I had the same problem, so googling I made these steps:

$ sudo pip install --upgrade virtualenv
$ virtualenv --system-site-packages ~/tensorflow
$ cd ~/tensorflow
$ source bin/activate
$ pip install --upgrade https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-0.5.0-cp27-none-linux_x86_64.whl
$ cd /tmp
$ wget http://launchpadlibrarian.net/137699828/libc6_2.17-0ubuntu5_amd64.deb
$ wget http://launchpadlibrarian.net/137699829/libc6-dev_2.17-0ubuntu5_amd64.deb
$ mkdir libc6_2.17
$ cd libc6_2.17
$ ar p ../libc6_2.17-0ubuntu5_amd64.deb data.tar.gz | tar zx
$ ar p ../libc6-dev_2.17-0ubuntu5_amd64.deb data.tar.gz | tar zx
$ cd -
$ LD_LIBRARY_PATH=/tmp/libc6_2.17/lib/x86_64-linux-gnu/ /tmp/libc6_2.17/lib/x86_64-linux-gnu/ld-2.17.so bin/python local/lib/python2.7/site-packages/tensorflow/models/image/mnist/convolutional.py

And to exit:

$ deactivate 

That works for me.

Roozbeh Zabihollahi
  • 7,207
  • 45
  • 39
Fabiano
  • 377
  • 4
  • 12
  • Solved my problem. Thanks! – Tanvir Nov 14 '15 at 18:59
  • Hey! @BR_User , which was the system you used? Was it Ubuntu 14.04? – Sahil Dec 26 '15 at 06:27
  • 1
    Oh, also @BR_User which architecture? Is it an intel or an amd? Just wondering if the libc6-dev_2.17 version might be different for the two – Sahil Dec 31 '15 at 11:31
  • I needed to add the ../ to the line: ar p ../libc6_2.17-0ubuntu5_amd64.deb data.tar.gz | tar zx – GavinBrelstaff Jan 19 '16 at 11:20
  • and similar: ar p ../libc6-dev_2.17-0ubuntu5_amd64.deb data.tar.gz | tar zx – GavinBrelstaff Jan 19 '16 at 11:21
  • 4
    but the path assignment still complains: bin/python: error while loading shared libraries: libpython2.7.so.1.0: cannot open shared object file: No such file or directory – GavinBrelstaff Jan 19 '16 at 11:22
  • It needs to be: `LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/tmp/libc6_2.17/lib/x86_64-linux-gnu blablabla`. For me worked e.g. this: `LD_LIBRARY_PATH=$LD_LIBRARY_PATH:"$HOME/my_libc_env/lib/x86_64-linux-gnu/:$HOME/my_libc_env/usr/lib64/" $HOME/my_libc_env/lib/x86_64-linux-gnu/ld-2.17.so `which python`` – kotrfa Feb 09 '16 at 11:30
  • 5
    Almost did it! Now it says: ImportError: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.19' not found (required by /home/yasen/tensorflow/local/lib/python2.7/site-packages/tensorflow/python/_pywrap_tensorflow.so) – Yasen May 20 '16 at 08:28
  • Do not do this, this will break your system. – loretoparisi Aug 31 '16 at 16:17
  • 2
    @loretoparisi, this solution would probably work OK for running simple scripts (adding new GLIBC to LD_LIBRARY_PATH and immediately starting specific python script). The console session would [get broken](https://github.com/tensorflow/tensorflow/issues/110#issuecomment-220009120) after doing that - just kill it afterwards. The **important thing is to never add these libraries to LD_LIBRARY_PATH permanently** (and to any "special folders" - just keep them in `/tmp`, like suggested here), and your system would be OK. – Igor Dec 06 '16 at 19:27
  • 2
    After finishing this it says ImportError: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.14' not found – MysticForce Jan 12 '17 at 15:56
  • The install url of the other tensorflow version can be found here: https://www.tensorflow.org/install/pip – cn123h Apr 25 '19 at 13:29
10

Okay so here is the other solution I mentionned in my previous answer, it's more tricky, but should always work on systems with GLIBC>=2.12 and GLIBCXX>=3.4.13. In my case it was on a CentOS 6.7, but it's also fine for Ubuntu 12.04.

We're going to need a version of gcc that supports c++11, either on another machine or an isolated install; but not for the moment.

What we're gonna do here is edit the _pywrap_tensorflow.so binary in order to 'weakify' its libc and libstdc++ dependencies, so that ld accepts to link the stubs we're gonna make. Then we'll make those stubs for the missing symbols, and finally we're gonna pre-load all of this when running python.

First of all, I want to thank James for his great article ( http://www.lightofdawn.org/wiki/wiki.cgi/NewAppsOnOldGlibc ) and precious advices, I couldn't have made it without him.

So let's start by weakifying the dependencies, it's just about replacing the right bytes in _pywrap_tensorflow.so. Please note that this step only works for the current version of tensorflow (0.6.0). So if its not done already create and activate your virtualenv if you have one (if you're not admin virtualenv is a solution, another is to add --user flag to pip command), and install tensorflow 0.6.0 (replace cpu by gpu in the url if you want the gpu version) :

pip install --upgrade https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-0.6.0-cp27-none-linux_x86_64.whl

And let's weakify all the annoying dependencies, here is the command for the cpu version of tensorflow:

TENSORFLOW_DIR=`python -c "import imp; print(imp.find_module('tensorflow')[1])"`
for addr in 0xC6A93C 0xC6A99C 0xC6A9EC 0xC6AA0C 0xC6AA1C 0xC6AA3C; do printf '\x02' | dd conv=notrunc of=${TENSORFLOW_DIR}/python/_pywrap_tensorflow.so bs=1 seek=$((addr)) ; done

And here is the gpu one (run only the correct one or you'll corrupt the binary):

TENSORFLOW_DIR=`python -c "import imp; print(imp.find_module('tensorflow')[1])"`
for addr in 0xDC5EA4 0xDC5F04 0xDC5F54 0xDC5F74 0xDC5F84 0xDC5FA4; do printf '\x02' | dd conv=notrunc of=${TENSORFLOW_DIR}/python/_pywrap_tensorflow.so bs=1 seek=$((addr)) ; done

You can check it with:

readelf -V ${TENSORFLOW_DIR}/python/_pywrap_tensorflow.so

Have a look at the article if you want to understand what's going on here.

Now we're gonna make the stubs for the missing libc symbols:

mkdir ~/my_stubs
cd ~/my_stubs
MYSTUBS=~/my_stubs
printf "#include <time.h>\n#include <string.h>\nvoid* memcpy(void *dest, const void *src, size_t n) {\nreturn memmove(dest, src, n);\n}\nint clock_gettime(clockid_t clk_id, struct timespec *tp) {\nreturn clock_gettime(clk_id, tp);\n}" > mylibc.c
gcc -s -shared -o mylibc.so -fPIC -fno-builtin mylibc.c

You need to perform that step on the machine with the missing dependencies (or machine with similar versions of standard libraries (in a cluster for example)).

Now we're gonna probably change of machine since we need a gcc that supports c++11, and it is probably not on the machine that lacks all the dependencies (or you can use an isolated install of a recent gcc). In the following I assume we're still in ~/my_stubs and somehow you share your home accross the machines, otherwise you'll just have to copy the .so files we're gonna generate when it's done.

So, one stub that we can do for libstdc++, and for the remaining missing ones we're going to compile them from gcc source (it might take some time to clone the repository):

printf "#include <functional>\nvoid std::__throw_bad_function_call(void) {\nexit(1);\n}" > bad_function.cc
gcc -std=c++11 -s -shared -o bad_function.so -fPIC -fno-builtin bad_function.cc
git clone https://github.com/gcc-mirror/gcc.git
cd gcc
mkdir my_include
mkdir my_include/ext
cp libstdc++-v3/include/ext/aligned_buffer.h my_include/ext
gcc -I$PWD/my_include -std=c++11 -fpermissive -s -shared -o $MYSTUBS/hashtable.so -fPIC -fno-builtin libstdc++-v3/src/c++11/hashtable_c++0x.cc
gcc -std=c++11 -fpermissive -s -shared -o $MYSTUBS/chrono.so -fPIC -fno-builtin libstdc++-v3/src/c++11/chrono.cc
gcc -std=c++11 -fpermissive -s -shared -o $MYSTUBS/random.so -fPIC -fno-builtin libstdc++-v3/src/c++11/random.cc
gcc -std=c++11 -fpermissive -s -shared -o $MYSTUBS/hash_bytes.so -fPIC -fno-builtin ./libstdc++-v3/libsupc++/hash_bytes.cc

And that's it! You can now run a tensorflow python script by preloading all our shared libraries (and your local libstdc++):

LIBSTDCPP=`ldconfig -p | grep libstdc++.so.6 | grep 64 | cut -d' ' -f4` #For 64bit machines
LD_PRELOAD="$MYSTUBS/mylibc.so:$MYSTUBS/random.so:$MYSTUBS/hash_bytes.so:$MYSTUBS/chrono.so:$MYSTUBS/hashtable.so:$MYSTUBS/bad_function.so:$LIBSTDCPP" python ${TENSORFLOW_DIR}/models/image/mnist/convolutional.py

:)

Community
  • 1
  • 1
Théo T
  • 3,270
  • 5
  • 20
  • 22
  • 1
    It looks like someone just posted a comment and then removed it, I'd love to have your opinion dear mysterious commenter :) – Théo T Jan 27 '16 at 13:28
  • Sure! Would like to note that the addresses need to be changed for the GPU version. I used readelf to obtain the following list (probably all of which aren't necessary; I added batches at a time): 0xDC5EA4 0xDC5EC4 0xDC5F04 0xDC5F54 0xDC5F64 0xDC5F74 0xDC5F84 0xDC5FA4 0xDC5FC4. One more note: it still doesn't work for me, but I think this is because of a Cuda driver issue (TF hangs when I instantiate a session). Will update if I confirm this. – rd11 Jan 27 '16 at 13:35
  • Oh that's weird, I tested it for the gpu version and it worked, I'll double check, are you using 0.6.0 version? Though i don't know about the hanging issue, keep me updated :) – Théo T Jan 27 '16 at 13:44
  • Yes, 0.6.0. I have a suspicion about it hanging. Exact same problem on another box (process hangs; even root can't kill -9). The problem on that box was the specific Cuda drivers installed alongside Cuda 7.0. We had to roll back to an older version. If I can get the admins of this server to try this, I'll update. – rd11 Jan 27 '16 at 13:46
  • Glad to hear that! And yes you're right, the gpu offsets are different, I must have messed with my virtualenvs when I first made it, thanks, I'll update that! – Théo T Jan 27 '16 at 14:13
  • 1
    Another small note: virtualenv isn't required if you're not admin. You just need to append `--user` to the `pip install`. – rd11 Jan 27 '16 at 14:50
  • I followed your post, but got errors after I cloned the gcc and try to compile using "gcc -std=c++11". It gave me error: cc1plus: error: unrecognized command line option "-std=c++11". It gave me error: "cc1plus: error: unrecognized command line option "-std=c++11" . My os is centos 6.7. Thanks! – ohmygoddess Mar 09 '16 at 21:34
  • Yes that's normal, as explained in the answer, you have to compile the libstdc++ symbols separately, typically on a machine with a more recent version of gcc that supports the 2011 C++ standard, and then copy back the .so files (it's actually something not to do in general, but needed (and working) here). – Théo T Mar 14 '16 at 15:52
  • Hey, @ThéoT, your solution works beautifully., except for one problem - segfault if something uses `clock_gettime`. Do you have any ideas how to circumvent that one? – Kostya Apr 19 '16 at 22:22
  • I've actually found a way. I just opened the `_pywrap_tensorflow.so` with a text editor. And replaced the two occurrences of `clock_gettime` with `clack_gettime`. Then renamed the exported function in `mylibc.c`. Now everything (jupyter notebook) works without crashing. – Kostya Apr 19 '16 at 22:35
  • Well that's weird, not sure of what's going on here, but as long as it works (cool hack btw :) ) – Théo T Apr 20 '16 at 10:23
2

Note to 'weakifying' solution of Theo Trouillon. It only applies for Tensorflow 0.6.0. If you want to apply it for Tensorflow 0.9.0, it gets trickier. My case was CPU mode, Centos 6.7 where GLIBC 2.12 GLIBCXX 3.4.13.

Installing tensorflow :

pip uninstall protobuf 
pip install --upgrade https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-0.9.0-cp27-none-linux_x86_64.whl

'weakifying' code should be CHANGED :

TENSORFLOW_DIR=`python -c "import imp; print(imp.find_module('tensorflow')[1])"`
for addr in 0x376e34 0x376e94 0x376ef4 0x376f14 0x376f24 0x376f44 0x376f54 ; do printf '\x02' | dd conv=notrunc of=${TENSORFLOW_DIR}/python/_pywrap_tensorflow.so bs=1 seek=$((addr)) ; done
for addr in 0x93aa4 0x93b04 ; do printf '\x02' | dd conv=notrunc of=${TENSORFLOW_DIR}/contrib/layers/python/ops/_bucketization_op.so bs=1 seek=$((addr)) ; done
for addr in 0x95bec 0x95c4c ; do printf '\x02' | dd conv=notrunc of=${TENSORFLOW_DIR}/contrib/layers/python/ops/_sparse_feature_cross_op.so bs=1 seek=$((addr)) ; done
for addr in 0x9ffec 0x9fffc 0xa005c ; do printf '\x02' | dd conv=notrunc of=${TENSORFLOW_DIR}/contrib/metrics/python/ops/_set_ops.so bs=1 seek=$((addr)) ; done
for addr in 0x96aa4 0x96b04 0x96b24; do printf '\x02' | dd conv=notrunc of=${TENSORFLOW_DIR}/contrib/linear_optimizer/python/ops/_sdca_ops.so bs=1 seek=$((addr)) ; done

And following code should be ADDED to the stub generating code at newer machine.

mkdir my_include/bits
cp libstdc++-v3/include/bits/shared_ptr_atomic.h my_include/bits/
cp libstdc++-v3/include/std/memory my_include/
gcc -I$PWD/my_include -std=c++11 -fpermissive -s -shared -o ${MYSTUBS}/shared_ptr.so -fPIC -fno-builtin ./libstdc++-v3/src/c++11/shared_ptr.cc
gcc -I$PWD/my_include -std=c++11 -fpermissive -s -shared -o ${MYSTUBS}/list.so -fPIC -fno-builtin ./libstdc++-v3/src/c++98/list.cc
echo "
#include <unistd.h>
#include <stdlib.h>
char * secure_getenv (const char *name) {
          if ((getuid () == geteuid ()) && (getgid () == getegid ())) return getenv (name); else  return NULL;
}" > getenv.cc
gcc -I$PWD/my_include  -std=c++11 -fpermissive -s -shared -o    ${MYSTUBS}/getenv.so -fPIC -fno-builtin getenv.cc

Of course the final running code should be changed to include additional stubs.

LD_PRELOAD="$MYSTUBS/list.so:$MYSTUBS/mylibc.so:$MYSTUBS/shared_ptr.so:$MYSTUBS/getenv.so:$MYSTUBS/random.so:$MYSTUBS/hash_bytes.so:$MYSTUBS/chrono.so:$MYSTUBS/hashtable.so:$MYSTUBS/bad_function.so:$LIBSTDCPP" python  ${TENSORFLOW_DIR}/models/image/mnist/convolutional.py
Tay Cho
  • 51
  • 1
  • 5
1

That error mainly arises if your GNU C-Library is not up-to-date. You can check what version you're running using a simple

$ ldd --version

The output should be like this:

ldd (Ubuntu EGLIBC 2.19-0ubuntu6.6) 2.19
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by Roland McGrath and Ulrich Drepper.

The 2.19 is your GLIBC version. To upgrade you can visit the GNU-C Library project website and download the latest version. The link to the latest glibc is here : GNU-C library Download At the time of writing this answer the latest stable version was 2.22.

I tried running tensorflow on both Ubuntu 12.04 and 14.04. Ubuntu 14.04 doesn't throw this issue as it comes with glibc 2.19 installed by default.

Hope it helps.

Community
  • 1
  • 1
shanky_thebearer
  • 233
  • 1
  • 11
  • 3
    Here be dragons: I compiled and installed glibc 2.23 under CentOS. Now every command (ls, vim and such ) causes segmentation fault...... – Utensil May 30 '16 at 10:11
  • `export LD_LIBRARY_PATH=""` or `/lib64/ld-linux-x86-64.so.2 --library-path /lib64 /bin/ls` temporarily fixed my problem, and I deleted newly modified `.so` files under `/usr/local/lib/` and everything seems to be fine now(also for compiling new programs). Please refer to https://sourceware.org/glibc/wiki/Testing/Builds – Utensil May 30 '16 at 14:02
1

My solution is similar to that of Theo T; although fine tuned for Xubuntu 12.04 (CAELinux 2013)

sudo pip install --upgrade https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-0.6.0-cp27-none-linux_x86_64.whl
sudo su
# prompt for password
TENSORFLOW_DIR=`python -c "import imp; print(imp.find_module('tensorflow')[1])"`
for addr in 0xC6A93C 0xC6A99C 0xC6A9EC 0xC6AA0C 0xC6AA1C 0xC6AA3C; do printf '\x02' | dd conv=notrunc of=${TENSORFLOW_DIR}/python/_pywrap_tensorflow.so bs=1 seek=$((addr)) ; done

readelf -V ${TENSORFLOW_DIR}/python/_pywrap_tensorflow.so
exit

mkdir ~/.my_stubs
cd ~/.my_stubs
MYSTUBS=~/.my_stubs


printf "#include <time.h>\n#include <string.h>\nvoid* memcpy(void *dest, const void *src, size_t n) {\nreturn memmove(dest, src, n);\n}\nint clock_gettime(clockid_t clk_id, struct timespec *tp) {\nreturn clock_gettime(clk_id, tp);\n}" > mylibc.c
gcc -s -shared -o mylibc.so -fPIC -fno-builtin mylibc.c

printf "#include <functional>\nvoid std::__throw_bad_function_call(void) {\nexit(1);\n}" > bad_function.cc
gcc -std=c++11 -s -shared -o bad_function.so -fPIC -fno-builtin bad_function.cc

git clone https://github.com/gcc-mirror/gcc.git

cd gcc
mkdir my_include
mkdir my_include/ext
cp libstdc++-v3/include/ext/aligned_buffer.h my_include/ext
gcc -I$PWD/my_include -std=c++11 -fpermissive -s -shared -o $MYSTUBS/hashtable.so -fPIC -fno-builtin libstdc++-v3/src/c++11/hashtable_c++0x.cc
gcc -std=c++11 -fpermissive -s -shared -o $MYSTUBS/chrono.so -fPIC -fno-builtin libstdc++-v3/src/c++11/chrono.cc
gcc -std=c++11 -fpermissive -s -shared -o $MYSTUBS/random.so -fPIC -fno-builtin libstdc++-v3/src/c++11/random.cc
gcc -std=c++11 -fpermissive -s -shared -o $MYSTUBS/hash_bytes.so -fPIC -fno-builtin ./libstdc++-v3/libsupc++/hash_bytes.cc

The following two steps would run the convolution.py script located in the tensorflow/models/image/mnist directory:

LIBSTDCPP=`ldconfig -p | grep libstdc++.so.6 | grep 64 | cut -d' ' -f4` #For 64bit machines
LD_PRELOAD="$MYSTUBS/mylibc.so:$MYSTUBS/random.so:$MYSTUBS/hash_bytes.so:$MYSTUBS/chrono.so:$MYSTUBS/hashtable.so:$MYSTUBS/bad_function.so:$LIBSTDCPP" python ${TENSORFLOW_DIR}/models/image/mnist/convolutional.py

If you want python to be always loaded with these reduced dependencies, simply add this to the .bashrc file with the below step:

echo "LIBSTDCPP=`ldconfig -p | grep libstdc++.so.6 | grep 64 | cut -d' ' -f4`" >> ~/.bashrc
echo alias python="'"LD_PRELOAD='"''$'MYSTUBS/mylibc.so:'$'MYSTUBS/random.so:'$'MYSTUBS/hash_bytes.so:'$'MYSTUBS/chrono.so:'$'MYSTUBS/hashtable.so:'$'MYSTUBS/bad_function.so:'$'LIBSTDCPP'"' python"'" >> ~/.bashrc

And if you have ipython:

echo alias ipython="'"LD_PRELOAD='"''$'MYSTUBS/mylibc.so:'$'MYSTUBS/random.so:'$'MYSTUBS/hash_bytes.so:'$'MYSTUBS/chrono.so:'$'MYSTUBS/hashtable.so:'$'MYSTUBS/bad_function.so:'$'LIBSTDCPP'"' ipython"'" >> ~/.bashrc

Basically, I updated it to the python installation being done in dist_packages instead of site-packages. Also, I clone from the gcc-mirror instead of the native git page for gcc. Rest all is the same.

The last few steps ensure that every time you run python or ipython, it would be loaded with the reduced dependencies.

Sam
  • 31
  • 3
  • Ah yes right it's in dist-packages in ubuntu, updated my answer to make it generic for any python install, thanks! – Théo T Jan 27 '16 at 13:58
  • But I still get the error :ImportError: ~/tensorflow/local/lib/python2.7/site-packages/tensorflow/python/_pywrap_tensorflow.so: symbol clock_gettime, version GLIBC_2.17 not defined in file libc.so.6 with link time reference – Sam Jan 28 '16 at 05:36
  • Solved it by repeating LD_PRELOAD="$MYSTUBS/mylibc.so:$MYSTUBS/random.so:$MYSTUBS/hash_bytes.so:$MYSTUBS/chrono.so:$MYSTUBS/hashtable.so:$MYSTUBS/bad_function.so:$LIBSTDCPP" python – Sam Jan 28 '16 at 05:45
  • How can I have LD_PRELOAD="..." python be repeated always? Sorry, but I'm just shell novice. – Sam Jan 28 '16 at 06:02
  • Yes you have to add LD_PRELOAD... first each time you run python. No worries, you can make yourself an alias and put it in your `~/.bashrc` to avoid writing it each time: `alias python='LD_PRELOAD="$MYSTUBS/mylibc.so:$MYSTUBS/random.so:$MYSTUBS/hash_bytes.so:$MYSTUB‌​S/chrono.so:$MYSTUBS/hashtable.so:$MYSTUBS/bad_function.so:$LIBSTDCPP" python'` . You can name it differently if you want to keep `python` command not preloading everything. Don't forget to add `MYSTUBS=~/.my_stubs` and `LIBSTDCPP=\`ldconfig -p | grep libstdc++.so.6 | grep 64 | cut -d' ' -f4\`` first in your `~/.bashrc` too ;) – Théo T Jan 28 '16 at 10:13
1

The link in @Théo T's answer is no longer working, so I had to try several alternatives to finally find one that works.

mkdir ~/my_libc_env
cd ~/my_libc_env
wget http://launchpadlibrarian.net/137699828/libc6_2.17-0ubuntu5_amd64.deb
wget http://launchpadlibrarian.net/137699829/libc6-dev_2.17-0ubuntu5_amd64.deb
wget ftp://ftp.icm.edu.pl/vol/rzm5/linux-slc/centos/7.0.1406/cr/x86_64/Packages/libstdc++-4.8.3-9.el7.x86_64.rpm
ar p libc6_2.17-0ubuntu5_amd64.deb data.tar.gz | tar zx
ar p libc6-dev_2.17-0ubuntu5_amd64.deb data.tar.gz | tar zx
rpm2cpio libstdc++-4.8.3-9.el7.x86_64.rpm| cpio -idmv

Run python code with tensorflow

LD_LIBRARY_PATH="$HOME/my_libc_env/lib/x86_64-linux-gnu/:$HOME/my_libc_env/usr/lib64/" $HOME/my_libc_env/lib/x86_64-linux-gnu/ld-2.17.so `which python` your_program.py
0

I have tried https://stackoverflow.com/a/34897674/5929065 solution, and its worked perfectly. But libstdc++-4.8.2-7 download link cannot be accessed any more, try to pick up a new one from this page: http://rpm.pbone.net/index.php3/stat/4/idpl/31981489/dir/centos_7/com/libstdc++-4.8.5-4.el7.x86_64.rpm.html

For me, I use this:

wget ftp://mirror.switch.ch/pool/4/mirror/centos/7.2.1511/os/x86_64/Packages/libstdc++-4.8.5-4.el7.x86_64.rpm

Community
  • 1
  • 1
0

Notice: you should download deb package by your platform:

x86:

https://launchpad.net/ubuntu/raring/i386/libc6/2.17-0ubuntu5.1

wget http://launchpadlibrarian.net/151932048/libc6_2.17-0ubuntu5.1_i386.deb

sudo dpkg -i libc6_2.17-0ubuntu5.1_i386.deb

x64:

https://launchpad.net/ubuntu/raring/amd64/libc6/2.17-0ubuntu5.1

wget http://launchpadlibrarian.net/151925896/libc6_2.17-0ubuntu5.1_amd64.deb

sudo dpkg -i libc6_2.17-0ubuntu5.1_amd64.deb

Test on my 12.04 Ubuntu x64.

Mithril
  • 12,947
  • 18
  • 102
  • 153
0

Above answers are fine but I still faced some issues even after doing them. I followed as in @Theo answer on rhel and I was trying to export LD_LIBRARY_PATH which had thrown some errors, along with LD_LIBRARY_PATH also include LD_PRELOAD as

mkdir libstdc
cd libstdc
rpm2cpio ../libstdc++-4.8.3-9.el7.x86_64.rpm| cpio -idmv
LD_LIBRARY_PATH="$HOME/my_libc_env/lib/x86_64-linux-gnu/:$HOME/my_libc_env/lib64/" LD_PRELOAD="$HOME/my_libc_env/libstdc/usr/lib64/libstdc++.so.6.0.19" $HOME/my_libc_env/lib/x86_64-linux-gnu/ld-2.17.so `which python`

you have to always do this while running python so make a script that loads these variables and calls python interpreter

vim tmp.sh

LD_LIBRARY_PATH="$HOME/my_libc_env/lib/x86_64-linux-gnu/:$HOME/my_libc_env/lib64/" LD_PRELOAD="$HOME/my_libc_env/libstdc/usr/lib64/libstdc++.so.6.0.19" $HOME/my_libc_env/lib/x86_64-linux-gnu/ld-2.17.so `which python`
rakesh
  • 4,368
  • 1
  • 19
  • 13
0

I got "version `GLIBC_2.14' not found" when importing tensorflow in python. Managed to import tensorflow in python3.5 on Centos6.6 using virtualenv:

mkdir ~/tensorflow
cd ~/tensorflow
virtualenv --system-site-packages -p python3.5 ~/tensorflow
source bin/activate
wget http://launchpadlibrarian.net/137699828/libc6_2.17-0ubuntu5_amd64.deb
wget http://launchpadlibrarian.net/137699829/libc6-dev_2.17-0ubuntu5_amd64.deb
wget ftp://195.220.108.108/linux/mageia/distrib/4/x86_64/media/core/updates/libstdc++6-4.8.2-3.2.mga4.x86_64.rpm
wget https://rpmfind.net/linux/centos/7.4.1708/updates/x86_64/Packages/glibc-2.17-196.el7_4.2.i686.rpm
ar p libc6_2.17-0ubuntu5_amd64.deb data.tar.gz | tar zx
ar p libc6-dev_2.17-0ubuntu5_amd64.deb data.tar.gz | tar zx
rpm2cpio libstdc++6-4.8.2-3.2.mga4.x86_64.rpm | cpio -idmv
rpm2cpio glibc-2.17-196.el7_4.2.i686.rpm | cpio -idmv
pip3.5 install --upgrade tensorflow
export PYTHONPATH="$HOME/tensorflow/lib/python3.5/site-packages/"
alias tfpython='LD_LIBRARY_PATH="$HOME/tensorflow/lib/x86_64-linux-gnu/:$HOME/tensorflow/usr/lib64/" $HOME/tensorflow/lib/x86_64-linux-gnu/ld-2.17.so /usr/local/bin/python3.5'
tfpython
breizhmg
  • 1,081
  • 8
  • 7
0

I had a similar problem trying to install numba on an old HPC Linux system running SUSE Linux Enterprise Server 11, which has glibc 2.11.3 (according to ldd --version). I have no superuser access, and any regular conda installation (either from the channels defaults, conda-forge, or numba) would fail with OSError: /lib64/libpthread.so.0: versionGLIBC_2.12not found (required by ...envs/test1-py37/lib/python3.7/site-packages/llvmlite/binding/libllvmlite.so). I managed to install numba by the following steps:

  1. Create a conda environment
  2. Inside the conda environment, install glibc from the nlsec environment
  3. Then use pip to install numba and llvmlite built against the newly installed glibc:

Thus:

conda create -n test -c nlesc glibc
conda activate test
pip install numba

Then importing numba works. However, one should subsequently be careful that any subsequent conda install does not "upgrade" llvmlite to a version not compatible with numba, or the old problem returns. You may want to pin either or both for this effect. You'll have to pin the build as well as the version. I created a file pinned containing:

llvmlite==0.27.0-pypi
numba==0.42.0-pypi

and placed it within my conda environment in a text file conda-meta/pinned.

gerrit
  • 24,025
  • 17
  • 97
  • 170
0

I had the same problem and found the following solution:

conda install tensorflow
Matt
  • 796
  • 12
  • 25