【问题标题】:Error while importing Tensorflow in Python 2.7 in Ubuntu 12.04. 'GLIBC_2.17 not found'在 Ubuntu 12.04 的 Python 2.7 中导入 Tensorflow 时出错。 '未找到 GLIBC_2.17'
【发布时间】:2018-04-26 06:02:43
【问题描述】:

我已经成功地用 python 安装了 Tensorflow 绑定。但是当我尝试导入 Tensorflow 时,我得到了以下错误。

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)

我尝试将 GLIBC_2.15 更新到 2.17,但没有成功。

【问题讨论】:

    标签: python ubuntu glibc tensorflow


    【解决方案1】:

    我刚刚设法在 CentOS 6.5 上使用 glibc 2.12 安装了 tensorflow 0.12rc0,没有 root 权限。简单地通过 pip 安装 tensorflow 二进制文件给了我一个错误,与 GLIBC 版本有关。

    基本上,您有 4 个选项来处理这个问题(每个选项都有一些优点和缺点):

    选项 1 - 全局升级您的系统 GLIBC。

    This is,可能是最好的选择,如果你的系统supports this,你有root权限,你相信这次升级不会因为一些奇怪的原因而破坏任何东西。最终,这会升级整个 Linux 发行版。 Here 是流行发行版中默认 GLIBC 版本的简短列表。

    选项 2 - 将第二个 GLIBC 添加到您的系统

    Compile or download binary。最简单直接的选择。特别是如果您只需要run few simple scripts

    • is possible 在同一系统上拥有多个版本的 glibc,但应该非常小心地执行此操作。
    • 如果您的所有更改仅限于虚拟环境,您就不会破坏您的系统。
    • 之前安装/编译的许多程序可能依赖于旧 GLIBC,would just crash 在您的新环境中(例如您的 python IDE)。包括最基本的 bash 命令,如“lc”、“cd”等。
    • significant memory leaks 等其他副作用也是可能的。
    • 因此,add new GLIBC to your normal environment 是一个非常糟糕的主意,例如通过.bashrc
    • 另一方面,如果您在新的虚拟环境中需要一些特定的工具,您可以recompile it, linking against new GLIBC。因此,它可以在您的新环境中正常工作。
    • 但是,就我个人而言,我很快放弃了在新环境中重新编译所需的一切(没有 root 和包管理器)。
    • slightly different approach 由 GLIBC 开发人员正式提供,用于测试新的 GLIBC 版本。

    选项 3 - 补丁张量流

    This 可能适用于 TF 0.6.0,但是当每个新的 tensorflow 版本发布时,您可能必须从头开始。例如。 here 是对 0.9.0 的修复。

    选项 4 - 从源代码编译 tensorflow

    如果您从源代码重新编译它并链接到您现有的 GLIBC,则不再需要更新的 GLIBC。不知何故,这里的任何答案都没有提到这个选项。恕我直言,这是“in general”和“专门用于 tensorflow”的最佳选择。

    • 这适用于 r0.11,并且可能会运行多年,但理论上,如果他们决定实际使用一些新的 GLIBC 功能,旧版本中不存在,它可能会在一些较新的 tensorflow 版本中中断。
    • 说实话,从源代码构建 TensorFlow 并不简单,尤其是在过时的系统上。

    “在过时系统上构建 tensorflow”的简要总结:

    虽然官方指南提供了“installing from sources”部分,但在过时的系统上构建它需要做一些技巧。在这里,我假设您没有 root 权限(如果您有 - 您可能可以使用包管理器安装相同的预请求,而不是从源代码手动构建它们)。

    我发现了两个有据可查的成功案例:#1#2 以及官方 github 上的一些有用帖子(主要是关于在二进制文件中链接的一组库):#1#2#3#4。在我的案例中,我必须结合那里描述的技巧才能成功编译 TF。

    1. 首先,检查您的gcc --versionverify 是否支持c++11。我的是 4.4.7,所以它不会工作。我有downloaded gcc-4.9.4 源代码和compiled it。这一步非常简单,但编译本身可能需要几个小时。作为 bazel 中问题的解决方法,我已将 gcc 与 hardcoded paths 编译为 asldnm。但是,您可以尝试其他解决方法:(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. 检查您的java --version。 Bazel 需要 JDK 8,如有必要,请安装它。 (他们仍然 provide 一些与 jdk7 相关的下载,用于 bazel-0.4.1 但看起来他们认为它已被弃用)

    3. 我创建了一个单独的use_gcc_4.9.4.sh 文件,其中包含必要的环境变量。当我需要与这个较新的编译器相关的东西时,我会使用source ./use_gcc_4.9.4.sh

      #!/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. 当前的 bazel 二进制 (0.4.1) requires GLIBC 2.14,所以我们也必须 compile bazel from source(使用我们的新 gcc)。工作正常,除非你在目标机器上只有allowed to run a very limited number of threads。 (This 帖子描述了一些额外的解决方法,但在我的情况下,它们并不需要,可能是由于最近更新了 bazel 代码。)

    5. 获取 tensorflow 源代码git clone https://github.com/tensorflow/tensorflow,并安装您需要的先决条件(CUDA、cuDNN、python 等)。见official guide

    6. 如果您不使用默认系统 gcc(例如,如果您必须编译更新的 gcc,如上所述),请将 the following linker flags 添加到 tensorflow/third_party/gpus/crosstool/CROSSTOOL.tplline 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"
      

      如果不执行此步骤,您可能会遇到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. 最后,为了避免 GLIBC 依赖,我们必须静态链接一些库,通过添加 -lrt 链接器标志(maybe -lm 也是如此)。我发现了多个帖子,建议以不同的方式添加:

      没有-lrt我又遇到了GLIBC-version-specific错误,尝试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)
      

      没有-lm,你可能会遇到this(对我来说,事实证明没有必要)。

    8. 运行构建过程。

        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. 尝试运行以下简单的 python 脚本来测试最基本的东西是否正常工作:

      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))
      

    【讨论】:

    • 当我配置 gcc 时得到了这个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
    • @Belter,这可能与操作系统有关。你确定你的“as”工作正常吗?也许您应该从键入“which as”开始并尝试执行它。反正这个问题和构建 gcc 比构建 tensorflow 更相关,所以和这个话题几乎没有关系。
    • 我由bazel build --config=opt //tensorflow/tools/pip_package:build_pip_package 构建,就像这里[tensorflow.org/install/install_sources] 建议,没有 gup。我将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" 添加到tensorflow/third_party/gpus/crosstool/CROSSTOOL.tpl,仍然出现错误...'GLIBCXX_3.4.20' not found..., ...'CXXABI_1.3.8' not found..., ...'GLIBCXX_3.4.18' not found...
    • 对于您的第二个选项,installation of glibc with conda 应该工作吗?我tried this,但它没有使它工作(glibc 来自nlescmgckind 保持相同的行为,glibc 来自asmeurer 给出python: error while loading shared libraries: __vdso_time: invalid mode for dlopen(): Invalid argument
    • @gerrit,我对这些软件包没有经验。理论上 - 它应该工作。在实践中 - 这取决于。首先检查您的路径环境变量,确保您没有从 venv 外部选择任何库,例如 thisLD_DEBUG 可能会有所帮助。
    【解决方案2】:

    我试过BR_User solution还是有一个烦人的:

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

    我在 CentOS 6.7 上,它还缺少更新的 c++ 标准库,因此为了构建 BR_User 解决方案,我提取了正确的 libstdc++ 包,但我发现不需要虚拟环境。

    假设你已经安装了 tensorflow,它给出:

    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
    

    然后运行python:

    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`
    

    如果它不起作用,我有another solution,但你不会喜欢它。

    【讨论】:

    【解决方案3】:

    我遇到了同样的问题,所以我用谷歌搜索了这些步骤:

    $ 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
    

    然后退出:

    $ deactivate 
    

    这对我有用。

    【讨论】:

    • 哦,还有@BR_User 哪个架构?是intel还是amd?只是想知道两者的 libc6-dev_2.17 版本是否可能不同
    • 但是路径分配仍然报错:bin/python: error while loading shared libraries: libpython2.7.so.1.0: cannot open shared object file: No such file or directory
    • 几乎做到了!现在它说: 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)
    • @loretoparisi,这个解决方案可能适用于运行简单的脚本(将新的 GLIBC 添加到 LD_LIBRARY_PATH 并立即启动特定的 python 脚本)。控制台会话将在这样做之后get broken - 之后将其杀死。 重要的是永远不要将这些库永久添加到 LD_LIBRARY_PATH(以及任何“特殊文件夹” - 只需将它们保存在 /tmp 中,就像这里建议的那样),您的系统就可以了。跨度>
    • 完成后显示 ImportError: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.14' not found
    【解决方案4】:

    好的,这是我在previous answer 中提到的另一个解决方案,它更棘手,但应该始终适用于 GLIBC>=2.12 和 GLIBCXX>=3.4.13 的系统。 就我而言,它是在 CentOS 6.7 上,但它也适用于 Ubuntu 12.04。

    我们将需要一个支持 c++11 的 gcc 版本,无论是在另一台机器上还是独立安装;但暂时没有。

    我们在这里要做的是编辑 _pywrap_tensorflow.so 二进制文件,以“弱化”它的 libc 和 libstdc++ 依赖项,以便 ld 接受链接我们要制作的存根。然后我们将为丢失的符号制作这些存根,最后我们将在运行 python 时预加载所有这些。

    首先,我要感谢 James 的精彩文章 (http://www.lightofdawn.org/wiki/wiki.cgi/NewAppsOnOldGlibc) 和宝贵的建议,没有他我无法做到。

    所以让我们从弱化依赖开始,它只是替换 _pywrap_tensorflow.so 中的正确字节。请注意,此步骤仅适用于当前版本的 tensorflow (0.6.0)。因此,如果尚未完成创建并激活您的virtualenv,如果您有一个(如果您不是管理员 virtualenv 是一种解决方案,另一种是将--user 标志添加到 pip 命令),并安装 tensorflow 0.6.0(替换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
    

    让我们弱化所有烦人的依赖,这里是 tensorflow 的 cpu 版本的命令:

    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
    

    这是一个 gpu(只运行正确的一个,否则会损坏二进制文件):

    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
    

    您可以通过以下方式进行检查:

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

    如果您想了解这里发生了什么,请查看这篇文章。

    现在我们要为丢失的 libc 符号制作存根:

    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
    

    需要在缺少依赖项的机器(或具有相似版本标准库的机器(例如在集群中))上执行该步骤。

    现在我们可能会更换机器,因为我们需要一个支持 c++11 的 gcc,而且它可能不在缺少所有依赖项的机器上(或者您可以使用最近 gcc 的隔离安装) .在下文中,我假设我们仍在~/my_stubs 中,并且您以某种方式在机器上共享您的家,否则您只需复制我们将在完成后生成的 .so 文件。

    所以,我们可以为 libstdc++ 做一个存根,而对于剩下的缺失的存根,我们将从 gcc 源代码编译它们(克隆存储库可能需要一些时间):

    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
    

    就是这样!您现在可以通过预加载我们所有的共享库(以及您本地的 libstdc++)来运行 tensorflow python 脚本:

    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
    

    :)

    【讨论】:

    • 好像有人刚刚发表评论然后删除了它,我很想听听你的意见亲爱的神秘评论者:)
    • 当然!需要注意的是,GPU 版本的地址需要更改。我使用 readelf 获得了以下列表(可能所有这些都不是必需的;我一次添加了批次):0xDC5EA4 0xDC5EC4 0xDC5F04 0xDC5F54 0xDC5F64 0xDC5F74 0xDC5F84 0xDC5FA4 0xDC5FC4。还有一点需要注意:它仍然对我不起作用,但我认为这是因为 Cuda 驱动程序问题(当我实例化会话时 TF 挂起)。如果我确认会更新。
    • 哦,这很奇怪,我测试了它的 gpu 版本,它工作正常,我会仔细检查,你使用的是 0.6.0 版本吗?虽然我不知道挂起的问题,但请让我更新:)
    • 是的,0.6.0。我怀疑它挂了。另一个盒子上的完全相同的问题(进程挂起;即使 root 也无法杀死 -9)。那个盒子上的问题是与 Cuda 7.0 一起安装的特定 Cuda 驱动程序。我们不得不回滚到旧版本。如果我能让这个服务器的管理员试试这个,我会更新。
    • 另一个小提示:如果您不是管理员,则不需要 virtualenv。您只需将--user 附加到pip install
    【解决方案5】:

    注意 Theo Trouillon 的“弱化”解决方案。它仅适用于 TensorFlow 0.6.0。如果你想将它应用于 Tensorflow 0.9.0,它会变得更加棘手。 我的情况是 CPU 模式,Centos 6.7,其中 GLIBC 2.12 GLIBCXX 3.4.13。

    安装张量流:

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

    “弱化”代码应该更改:

    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
    

    以下代码应添加到较新机器上的存根生成代码中。

    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
    

    当然,最终运行的代码应该更改为包含额外的存根。

    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
    

    【讨论】:

      【解决方案6】:

      如果您的 GNU C-Library 不是最新的,则主要会出现该错误。 您可以使用简单的方法检查您正在运行的版本

      $ ldd --version
      

      输出应该是这样的:

      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.
      

      2.19 是您的 GLIBC 版本。要升级,您可以访问 GNU-C 库项目网站并下载最新版本。 最新 glibc 的链接在这里:GNU-C library Download 在撰写此答案时,最新的稳定版本是 2.22

      我尝试在 Ubuntu 12.04 和 14.04 上运行 tensorflow。 Ubuntu 14.04 不会抛出这个问题,因为它默认安装了 glibc 2.19。

      希望对你有帮助。

      【讨论】:

      • 这里是龙:我在 CentOS 下编译并安装了 glibc 2.23。现在每个命令(ls、vim 等)都会导致分段错误......
      • export LD_LIBRARY_PATH=""/lib64/ld-linux-x86-64.so.2 --library-path /lib64 /bin/ls 暂时解决了我的问题,我删除了/usr/local/lib/ 下新修改的.so 文件,现在一切似乎都很好(也用于编译新程序)。请参考sourceware.org/glibc/wiki/Testing/Builds
      【解决方案7】:

      我的解决方案与 Theo T 的类似;尽管针对 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
      

      以下两个步骤将运行位于 tensorflow/models/image/mnist 目录中的 convolution.py 脚本:

      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
      

      如果您希望 python 始终加载这些减少的依赖项,只需通过以下步骤将其添加到 .bashrc 文件中:

      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
      

      如果你有 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
      

      基本上,我将它更新为在 dist_packages 而不是 site-packages 中完成的 python 安装。另外,我从gcc-mirror 克隆而不是 gcc 的本机 git 页面。其余的都是一样的。

      最后几个步骤确保每次运行 python 或 ipython 时,都会加载减少的依赖项。

      【讨论】:

      • 啊,是的,它在 ubuntu 的 dist-packages 中,更新了我的答案,使其适用于任何 python 安装,谢谢!
      • 但我仍然得到错误:ImportError: ~/tensorflow/local/lib/python2.7/site-packages/tensorflow/python/_pywrap_tensorflow.so: 符号clock_gettime,版本GLIBC_2.17 未定义在带有链接时间参考的文件 libc.so.6 中
      • 通过重复 LD_PRELOAD="$MYSTUBS/mylibc.so:$MYSTUBS/random.so:$MYSTUBS/hash_bytes.so:$MYSTUBS/chrono.so:$MYSTUBS/hashtable.so: $MYSTUBS/bad_function.so:$LIBSTDCPP" python
      • 我怎样才能让 LD_PRELOAD="..." python 总是重复?抱歉,我只是 shell 新手。
      • 是的,您必须在每次运行 python 时首先添加 LD_PRELOAD...。不用担心,您可以给自己起一个别名并将其放入您的~/.bashrc 以避免每次都写它: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'。如果您想保持python 命令不预加载所有内容,您可以将其命名为不同的名称。不要忘记在您的~/.bashrc 中添加MYSTUBS=~/.my_stubsLIBSTDCPP=`ldconfig -p | grep libstdc++.so.6 | grep 64 | cut -d' ' -f4` ;)
      【解决方案8】:

      @Théo T 答案中的链接不再有效,因此我不得不尝试几种替代方法,最终找到一种有效的方法。

      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
      

      使用 tensorflow 运行 python 代码

      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
      

      【讨论】:

        【解决方案9】:

        我已经尝试过https://stackoverflow.com/a/34897674/5929065 解决方案,并且效果很好。但是libstdc++-4.8.2-7的下载链接已经无法访问了,尝试从这个页面重新下载一个:http://rpm.pbone.net/index.php3/stat/4/idpl/31981489/dir/centos_7/com/libstdc++-4.8.5-4.el7.x86_64.rpm.html

        对我来说,我用这个:

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

        【讨论】:

          【解决方案10】:

          注意:你应该根据你的平台下载deb包:

          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
          

          在我的 12.04 Ubuntu x64 上测试。

          【讨论】:

            【解决方案11】:

            上面的答案很好,但即使在完成之后我仍然遇到了一些问题。我按照关于 rhel 的@Theo 回答进行了操作,我试图导出引发了一些错误的 LD_LIBRARY_PATH,同时 LD_LIBRARY_PATH 还包括 LD_PRELOAD 作为

            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`
            

            你必须在运行 python 时总是这样做,所以制作一个脚本来加载这些变量并调用 python 解释器

            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`
            

            【讨论】:

              【解决方案12】:

              在 python 中导入 tensorflow 时出现“未找到版本 `GLIBC_2.14'”。使用 virtualenv 在 Centos6.6 上的 python3.5 中导入 tensorflow:

              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
              

              【讨论】:

                【解决方案13】:

                我在尝试在运行的旧 HPC Linux 系统上安装 numba 时遇到了类似的问题 SUSE Linux Enterprise Server 11,具有 glibc 2.11.3(根据 ldd --version)。我没有超级用户访问权限,任何常规的 conda 安装(来自频道 defaultsconda-forgenumba)都会失败,并显示 OSError: /lib64/libpthread.so.0: versionGLIBC_2.12not found (required by ...envs/test1-py37/lib/python3.7/site-packages/llvmlite/binding/libllvmlite.so)。我设法通过以下步骤安装了numba

                1. 创建 conda 环境
                2. 在 conda 环境中,从 nlsec 环境安装 glibc
                3. 然后使用pip安装numballvmlite针对新安装的glibc构建:

                因此:

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

                然后导入 numba 工作。但是,随后应注意任何后续的conda install 不会“升级”llvmlite 到与numba 不兼容的版本,否则旧问题会再次出现。您可能需要to pin 中的一个或两个来实现此效果。您必须固定构建以及版本。我创建了一个文件pinned,其中包含:

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

                并将其放在我的 conda 环境中的文本文件 conda-meta/pinned

                【讨论】:

                  【解决方案14】:

                  我也遇到了同样的问题,found the following solution:

                  conda install tensorflow
                  

                  【讨论】:

                    猜你喜欢
                    • 2016-02-17
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2013-06-16
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多