Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ImportError: libtorch_cpu.so: cannot enable executable stack as shared object requires: Invalid argument #350

Closed
1 task done
function2-llx opened this issue Feb 9, 2025 · 17 comments
Labels
bug Something isn't working

Comments

@function2-llx
Copy link

function2-llx commented Feb 9, 2025

Solution to issue cannot be found in the documentation.

  • I checked the documentation.

Issue

I create a minimal environment with PyTorch (with command mamba create -n ttt python=3.11 pytorch), then I get the following error when imporing PyTorch (with python -c 'import torch'):

ImportError: libtorch_cpu.so: cannot enable executable stack as shared object requires: Invalid argument

I am using Arch Linux and the kernel version is 6.13.2-arch1-1, this issue seems to appear after a recent system upgrade (I can try rolling it back, but since it would be a huge effort for me, I have to do it later).

I am not sure if here is the most appropriate place to ask. But since I can import torch successfully if installed with pip, I would appreciate any hint or suggestion.

Installed packages

Name                  Version     Build                           Channel    
─────────────────────────────────────────────────────────────────────────────────
  _libgcc_mutex         0.1         conda_forge                     conda-forge
  _openmp_mutex         4.5         2_kmp_llvm                      conda-forge
  attr                  2.5.1       h166bdaf_1                      conda-forge
  bzip2                 1.0.8       h4bc722e_7                      conda-forge
  ca-certificates       2025.1.31   hbcca054_0                      conda-forge
  cpython               3.11.11     py311hd8ed1ab_1                 conda-forge
  cuda-crt-tools        12.8.61     ha770c72_1                      conda-forge
  cuda-cudart           12.8.57     h5888daf_0                      conda-forge
  cuda-cudart_linux-64  12.8.57     h3f2d84a_0                      conda-forge
  cuda-cuobjdump        12.8.55     hbd13f7d_0                      conda-forge
  cuda-cupti            12.8.57     hbd13f7d_0                      conda-forge
  cuda-nvcc-tools       12.8.61     he02047a_1                      conda-forge
  cuda-nvdisasm         12.8.55     hbd13f7d_0                      conda-forge
  cuda-nvrtc            12.8.61     hbd13f7d_0                      conda-forge
  cuda-nvtx             12.8.55     hbd13f7d_0                      conda-forge
  cuda-nvvm-tools       12.8.61     he02047a_1                      conda-forge
  cuda-version          12.8        h5d125a7_3                      conda-forge
  cudnn                 9.7.1.26    h969bcc4_0                      conda-forge
  cusparselt            0.6.3.2     hdea8103_1                      conda-forge
  filelock              3.17.0      pyhd8ed1ab_0                    conda-forge
  fsspec                2025.2.0    pyhd8ed1ab_0                    conda-forge
  gmp                   6.3.0       hac33072_2                      conda-forge
  gmpy2                 2.1.5       py311h0f6cedb_3                 conda-forge
  jinja2                3.1.5       pyhd8ed1ab_0                    conda-forge
  ld_impl_linux-64      2.43        h712a8e2_2                      conda-forge
  libabseil             20240722.0  cxx17_hbbce691_4                conda-forge
  libblas               3.9.0       28_h2556b6b_mkl                 conda-forge
  libcap                2.71        h39aace5_0                      conda-forge
  libcblas              3.9.0       28_h372d94f_mkl                 conda-forge
  libcublas             12.8.3.14   h9ab20c4_0                      conda-forge
  libcudss0             0.4.0.2     he55f5cd_2                      conda-forge
  libcufft              11.3.3.41   hbd13f7d_0                      conda-forge
  libcufile             1.13.0.11   h12f29b5_0                      conda-forge
  libcurand             10.3.9.55   hbd13f7d_0                      conda-forge
  libcusolver           11.7.2.55   h9ab20c4_0                      conda-forge
  libcusparse           12.5.7.53   hbd13f7d_0                      conda-forge
  libexpat              2.6.4       h5888daf_0                      conda-forge
  libffi                3.4.2       h7f98852_5                      conda-forge
  libgcc                14.2.0      h77fa898_1                      conda-forge
  libgcc-ng             14.2.0      h69a702a_1                      conda-forge
  libgcrypt-lib         1.11.0      hb9d3cd8_2                      conda-forge
  libgpg-error          1.51        hbd13f7d_1                      conda-forge
  libhwloc              2.11.2      default_h0d58e46_1001           conda-forge
  libiconv              1.17        hd590300_2                      conda-forge
  liblapack             3.9.0       28_hc41d3b0_mkl                 conda-forge
  libllvm19             19.1.7      ha7bfdaf_1                      conda-forge
  liblzma               5.6.4       hb9d3cd8_0                      conda-forge
  libmagma              2.8.0       h566cb83_2                      conda-forge
  libnl                 3.11.0      hb9d3cd8_0                      conda-forge
  libnsl                2.0.1       hd590300_0                      conda-forge
  libnvjitlink          12.8.61     hbd13f7d_0                      conda-forge
  libprotobuf           5.28.3      h6128344_1                      conda-forge
  libsqlite             3.48.0      hee588c1_1                      conda-forge
  libstdcxx             14.2.0      hc0a3c3a_1                      conda-forge
  libstdcxx-ng          14.2.0      h4852527_1                      conda-forge
  libsystemd0           257.2       h3dc2cb9_0                      conda-forge
  libtorch              2.5.1       cuda126_mkl_haa0cf67_310        conda-forge
  libudev1              257.2       h9a4d06a_0                      conda-forge
  libuuid               2.38.1      h0b41bf4_0                      conda-forge
  libuv                 1.50.0      hb9d3cd8_0                      conda-forge
  libxcrypt             4.4.36      hd590300_1                      conda-forge
  libxml2               2.13.5      h0d44e9d_1                      conda-forge
  libzlib               1.3.1       hb9d3cd8_2                      conda-forge
  llvm-openmp           19.1.7      h024ca30_0                      conda-forge
  lz4-c                 1.10.0      h5888daf_1                      conda-forge
  markupsafe            3.0.2       py311h2dc5d0c_1                 conda-forge
  mkl                   2024.2.2    ha957f24_16                     conda-forge
  mpc                   1.3.1       h24ddda3_1                      conda-forge
  mpfr                  4.2.1       h90cbb55_3                      conda-forge
  mpmath                1.3.0       pyhd8ed1ab_1                    conda-forge
  nccl                  2.25.1.1    ha44e49d_0                      conda-forge
  ncurses               6.5         h2d0b736_3                      conda-forge
  networkx              3.4.2       pyh267e887_2                    conda-forge
  numpy                 2.2.2       py311h5d046bc_0                 conda-forge
  openssl               3.4.0       h7b32b05_1                      conda-forge
  pip                   25.0        pyh8b19718_0                    conda-forge
  python                3.11.11     h9e4cc4f_1_cpython              conda-forge
  python_abi            3.11        5_cp311                         conda-forge
  pytorch               2.5.1       cuda126_mkl_py311_h3846359_310  conda-forge
  pytorch-gpu           2.5.1       cuda126_mkl_ha999a5f_310        conda-forge
  rdma-core             56.0        h5888daf_0                      conda-forge
  readline              8.2         h8228510_1                      conda-forge
  setuptools            75.8.0      pyhff2d567_0                    conda-forge
  sleef                 3.8         h1b44611_0                      conda-forge
  sympy                 1.13.3      pyh2585a3b_105                  conda-forge
  tbb                   2021.13.0   hceb3a55_1                      conda-forge
  tk                    8.6.13      noxft_h4845f30_101              conda-forge
  triton                3.1.0       cuda126py311hd5e47cf_6          conda-forge
  typing_extensions     4.12.2      pyha770c72_1                    conda-forge
  tzdata                2025a       h78e105d_0                      conda-forge
  wheel                 0.45.1      pyhd8ed1ab_1                    conda-forge
  zstd                  1.5.6       ha6fb4c9_0                      conda-forge

Environment info

libmamba version : 2.0.5
     micromamba version : 2.0.5
           curl version : libcurl/8.11.1 OpenSSL/3.4.0 zlib/1.3.1 zstd/1.5.6 libssh2/1.11.1 nghttp2/1.64.0
     libarchive version : libarchive 3.7.7 zlib/1.3.1 bz2lib/1.0.8 libzstd/1.5.6
       envs directories : /home/function2/micromamba/envs
          package cache : /home/function2/micromamba/pkgs
                          /home/function2/.mamba/pkgs
            environment : ttt (active)
           env location : /home/function2/micromamba/envs/ttt
      user config files : /home/function2/.mambarc
 populated config files : /home/function2/.condarc
       virtual packages : __unix=0=0
                          __linux=6.13.2=0
                          __glibc=2.41=0
                          __archspec=1=x86_64_v4
                          __cuda=12.7=0
               channels : https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64
                          https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/noarch
       base environment : /home/function2/micromamba
               platform : linux-64
@function2-llx function2-llx added the bug Something isn't working label Feb 9, 2025
@mgorny
Copy link
Contributor

mgorny commented Feb 9, 2025

I've just asked around, and the answer I got is that glibc 2.41 prohibits dlopening libraries with executable stacks. We'll have to figure out which library does this, though.

@mgorny
Copy link
Contributor

mgorny commented Feb 9, 2025

Yep, I can reproduce. I wish I'd knew that before i upgraded glibc today :-).

Please note that generally it isn't safe to downgrade glibc.

@mgorny
Copy link
Contributor

mgorny commented Feb 9, 2025

Ok, so apparently it isn't coming from any of the shared dependencies but from libtorch_cpu.so itself.

@mgorny
Copy link
Contributor

mgorny commented Feb 9, 2025

Ok, so far confirmed that;

  1. It happens with pure CPU and generic BLAS variant too.
  2. Upstream 2.5.1 .whl for the CPU variant works.
  3. The problem goes back to the 0 build of 2.5.1, and also 2.4.0 — so it's not anything we've changed recently.

@mgorny
Copy link
Contributor

mgorny commented Feb 9, 2025

$BUILD_PREFIX/bin/../lib/gcc/x86_64-conda-linux-gnu/13.3.0/../../../../x86_64-conda-linux-gnu/bin/ld: warning: ittptmark64.S.o: missing .note.GNU-stack section implies executable stack

I guess that's the problem.

@h-vetinari
Copy link
Member

h-vetinari commented Feb 9, 2025

This has the potential to turn into a bigger problem actually, because GCC's nested function extension uses an executable stack - see here for some background. We can only hope that this changed with more recent GCC versions, but I'm not sure if that's even possible due to ABI. Otherwise any project that uses said extension on linux might be affected.

@function2-llx
Copy link
Author

function2-llx commented Feb 10, 2025

Thanks for the information! So currently there are two workarounds:

  1. Clear the executable stack flag with execstack -c $CONDA_PREFIX/lib/libtorch_cpu.so. I've tried this approach and it works for me.
    • So I am wondering would a fix be linking libtorch_cpu.so with executable stack disabled with something like -Wl,-z,noexecstack?
  2. Downgrade glibc to 2.40. I have not tried it yet but is reported to work elsewhere.

Related discussions:

@thesamesam
Copy link

We can only hope that this changed with more recent GCC versions, but I'm not sure if that's even possible due to ABI.

GCC can use the heap for the trampoline for some ABIs now.

@h-vetinari
Copy link
Member

Thanks for the information! Do you also happen to know since which GCC version(s) linux-{x86_64,aarch,powerpc64le} have that ability (respectively), and do we need to anything to opt into the heap-trampoline, or is it the default?

@thesamesam
Copy link

thesamesam commented Feb 10, 2025

GCC 14 (r14-4821-g28d8c680aaea46 and a few commits after) implemented it with -ftrampoline-impl=heap (docs):

These functions are implemented in libgcc, and will only be provided on specific targets: x86_64 Darwin, x86_64 and aarch64 Linux.

The default is still on the stack - I don't know what the blocker is there for changing it to heap where appropriate (@iains?)

I don't, at a glance, see these in the Changes pages for GCC 14, which I'm going to handle now (EDIT: patch).

@h-vetinari
Copy link
Member

Thank you very much for all that. 🙏

If it becomes too painful, we might have to accelerate our switch to GCC 14 (normally we wait until the patch release after the next major version, so 14.3). And I guess ppc will just have to live with the workarounds until GCC ever learns -ftrampoline-impl=heap for that target.

@iains
Copy link

iains commented Feb 10, 2025

For SysV targets, I would expect copying the approach used for X86_64/Aarch64 would work. For BSD-style targets maybe copying the approach used by Darwin. I guess it's too late for GCC-15 (PPC) since the patch would need to be approved by the platform maintainer (but of course you could make a patch and see if it is acceptable)

@function2-llx
Copy link
Author

function2-llx commented Feb 10, 2025

because GCC's nested function extension uses an executable stack

@h-vetinari Out of curiosity, could you please give some examples on what libraries are using the GCC's nested function extension?

@h-vetinari
Copy link
Member

I don't have a good answer for you on that, but it's a long-standing extension that very likely has a bunch of users. Probably less so on projects that focus on cross-platform support (because there the code then isn't usable on osx/win, at least not with the default compilers of that platform), but I'd imagine several linux-focused projects to have used this. It's a useful pattern, even though it's not standard C. For more details see the article I posted.

@iains
Copy link

iains commented Feb 10, 2025

You should also be aware that other core languages (Ada, Fortran) also use nested functions "under the hood" so it's not just explicit use in C that matters to the overall "downstream".

mgorny added a commit to mgorny/pytorch-cpu-feedstock that referenced this issue Feb 10, 2025
Explicitly pass `-Wl,-z,noexecstack` to the linker, to ensure that
`libpytorch_cpu.so` is compiled without an executable stack.  This is
necessary because the raw assembly in oneDNN triggers:

```
$BUILD_PREFIX/bin/../lib/gcc/x86_64-conda-linux-gnu/13.3.0/../../../../x86_64-conda-linux-gnu/bin/ld: warning: ittptmark64.S.o: missing .note.GNU-stack section implies executable stack
```

...and glibc 2.41 no longer permits loading libraries with executable
stack.

Fixes conda-forge#350
@mgorny
Copy link
Contributor

mgorny commented Feb 10, 2025

#355 fixes it for me.

h-vetinari pushed a commit to h-vetinari/pytorch-cpu-feedstock that referenced this issue Feb 10, 2025
Explicitly pass `-Wl,-z,noexecstack` to the linker, to ensure that
`libpytorch_cpu.so` is compiled without an executable stack.  This is
necessary because the raw assembly in oneDNN triggers:

```
$BUILD_PREFIX/bin/../lib/gcc/x86_64-conda-linux-gnu/13.3.0/../../../../x86_64-conda-linux-gnu/bin/ld: warning: ittptmark64.S.o: missing .note.GNU-stack section implies executable stack
```

...and glibc 2.41 no longer permits loading libraries with executable
stack.

Fixes conda-forge#350
h-vetinari pushed a commit that referenced this issue Feb 11, 2025
Explicitly pass `-Wl,-z,noexecstack` to the linker, to ensure that
`libpytorch_cpu.so` is compiled without an executable stack.  This is
necessary because the raw assembly in oneDNN triggers:

```
$BUILD_PREFIX/bin/../lib/gcc/x86_64-conda-linux-gnu/13.3.0/../../../../x86_64-conda-linux-gnu/bin/ld: warning: ittptmark64.S.o: missing .note.GNU-stack section implies executable stack
```

...and glibc 2.41 no longer permits loading libraries with executable
stack.

Fixes #350
@h-vetinari
Copy link
Member

#355 fixes it for me.

Thanks a lot for the PR and the confirmation! I've picked #355 into #346 (also into #326 for the upcoming 2.6), which was just merged, so I'm closing this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants