conda-forge / ctng-compilers-feedstock

A conda-smithy repository for ctng-compilers.
BSD 3-Clause "New" or "Revised" License
12 stars 26 forks source link

libstdc++ is missing `gdb` pretty-printer integration #105

Open upsj opened 2 years ago

upsj commented 2 years ago

Solution to issue cannot be found in the documentation.

Issue

On most system package managers, libstdc++ provides an automatic integration into gdb by placing a file into share/gdb/auto-load that loads the pretty-printers that are present in share/gcc-x.x.x/python/libstdcxx. This integration seems to be missing from conda, which makes debugging binaries that were compiled with conda's C++ compiler unnecessarily tedious.

Two possible solutions to this would be 1. creating a custom gdbinit file that sets the auto-load safe-path and loads the file or 2. creating the file in the expected location for libstdc++.so in the first place, which can be seen by running gdb on a simple C++ test program:

> gdb ./test
> set debug auto-load on
> run
...
auto-load: Attempted file "/usr/share/gdb/auto-load/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.28-gdb.py" exists.
auto-load: Loading python script "/usr/share/gdb/auto-load/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.28-gdb.py" by extension for objfile "/lib/x86_64-linux-gnu/libstdc++.so.6".
auto-load: Matching file "/usr/share/gdb/auto-load/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.28-gdb.py" to pattern "/usr/lib/debug"
auto-load: Not matched - pattern "/usr/lib/debug".
auto-load: Matching file "/usr/share/gdb/auto-load/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.28-gdb.py" to pattern "/usr/share/gdb/auto-load"
auto-load: Matched - file "/usr/share/gdb/auto-load" to pattern "/usr/share/gdb/auto-load"
...

Installed packages

# packages in environment at /root/miniconda3:
#
# Name                    Version                   Build  Channel
_libgcc_mutex             0.1                        main  
_openmp_mutex             4.5                       1_gnu  
binutils                  2.35.1               hdd6e379_2    conda-forge
binutils_impl_linux-64    2.35.1               h27ae35d_9  
binutils_linux-64         2.35                h67ddf6f_30    conda-forge
brotlipy                  0.7.0           py39h27cfd23_1003  
c-compiler                1.2.0                h7f98852_0    conda-forge
ca-certificates           2022.6.15            ha878542_0    conda-forge
certifi                   2022.6.15        py39hf3d152e_0    conda-forge
cffi                      1.15.0           py39hd667e15_1  
charset-normalizer        2.0.4              pyhd3eb1b0_0  
colorama                  0.4.4              pyhd3eb1b0_0  
conda                     4.13.0           py39hf3d152e_1    conda-forge
conda-content-trust       0.1.1              pyhd3eb1b0_0  
conda-package-handling    1.8.1            py39h7f8727e_0  
cryptography              36.0.0           py39h9ce1e76_0  
cxx-compiler              1.2.0                h4bd325d_0    conda-forge
gcc_impl_linux-64         9.3.0               h70c0ae5_19    conda-forge
gcc_linux-64              9.3.0               hf25ea35_30    conda-forge
gdb                       11.2             py39he3c4487_2  
gxx_impl_linux-64         9.3.0               hd87eabc_19    conda-forge
gxx_linux-64              9.3.0               h3fbe746_30    conda-forge
idna                      3.3                pyhd3eb1b0_0  
kernel-headers_linux-64   2.6.32              he073ed8_15    conda-forge
ld_impl_linux-64          2.35.1               h7274673_9  
libffi                    3.3                  he6710b0_2  
libgcc-devel_linux-64     9.3.0               h7864c58_19    conda-forge
libgcc-ng                 9.3.0               h5101ec6_17  
libgomp                   9.3.0               h5101ec6_17  
libstdcxx-devel_linux-64  9.3.0               hb016644_19    conda-forge
libstdcxx-ng              11.2.0               h1234567_1  
ncurses                   6.3                  h7f8727e_2  
openssl                   1.1.1q               h7f8727e_0  
pip                       21.2.4           py39h06a4308_0  
pycosat                   0.6.3            py39h27cfd23_0  
pycparser                 2.21               pyhd3eb1b0_0  
pygments                  2.11.2             pyhd3eb1b0_0  
pyopenssl                 22.0.0             pyhd3eb1b0_0  
pysocks                   1.7.1            py39h06a4308_0  
python                    3.9.12               h12debd9_0  
python_abi                3.9                      2_cp39    conda-forge
readline                  8.1.2                h7f8727e_1  
requests                  2.27.1             pyhd3eb1b0_0  
ruamel_yaml               0.15.100         py39h27cfd23_0  
setuptools                61.2.0           py39h06a4308_0  
six                       1.16.0             pyhd3eb1b0_1  
sqlite                    3.38.2               hc218d9a_0  
sysroot_linux-64          2.12                he073ed8_15    conda-forge
tk                        8.6.11               h1ccaba5_0  
tqdm                      4.63.0             pyhd3eb1b0_0  
tzdata                    2022a                hda174b7_0  
urllib3                   1.26.8             pyhd3eb1b0_0  
wheel                     0.37.1             pyhd3eb1b0_0  
xz                        5.2.5                h7b6447c_0  
yaml                      0.2.5                h7b6447c_0  
zlib                      1.2.12               h7f8727e_1

Environment info

active environment : base
    active env location : /root/miniconda3
            shell level : 1
       user config file : /root/.condarc
 populated config files : 
          conda version : 4.13.0
    conda-build version : not installed
         python version : 3.9.12.final.0
       virtual packages : __linux=5.4.0=0
                          __glibc=2.31=0
                          __unix=0=0
                          __archspec=1=x86_64
       base environment : /root/miniconda3  (writable)
      conda av data dir : /root/miniconda3/etc/conda
  conda av metadata url : None
           channel URLs : https://repo.anaconda.com/pkgs/main/linux-64
                          https://repo.anaconda.com/pkgs/main/noarch
                          https://repo.anaconda.com/pkgs/r/linux-64
                          https://repo.anaconda.com/pkgs/r/noarch
          package cache : /root/miniconda3/pkgs
                          /root/.conda/pkgs
       envs directories : /root/miniconda3/envs
                          /root/.conda/envs
               platform : linux-64
             user-agent : conda/4.13.0 requests/2.27.1 CPython/3.9.12 Linux/5.4.0-110-generic ubuntu/20.04.4 glibc/2.31
                UID:GID : 0:0
             netrc file : None
           offline mode : False
isuruf commented 2 years ago

The file is included wrongly as $PREFIX/lib/*-gdb.py. Can you figure out the reason and send a PR to fix it?

upsj commented 2 years ago

I am somewhat new to conda, so I have three questions to investigate this further

  1. I ran build-locally.py successfully. How do I now install the newly built packages, to see where they are placed?
  2. Do we need to check whether we're cross-compiling? The commented out
    # Probably don't want to do this for cross-compilers
    # mkdir -p ${PREFIX}/share/gdb/auto-load/usr/lib/
    # cp ${SRC_DIR}/gcc_built/${CHOST}/sysroot/lib/libstdc++.so.6.*-gdb.py ${PREFIX}/share/gdb/auto-load/usr/lib/

    seems to suggest so, but it might need the target triplet x86_64-conda-linux-gnu as a prefix, to match the location of libstdc++.so

  3. It seems like the standard library .so is provided by multiple packages:
    ./libstdcxx-ng-9.5.0-hf86b28c_16/lib/libstdc++.so.6.0.28
    ./gxx_impl_linux-64-9.5.0-h6c5bc03_16/lib/libstdc++.so.6.0.28-gdb.py
    ./gcc_bootstrap_linux-64-9.5.0-hf039093_10/lib/libstdc++.so.6.0.28-gdb.py
    ./gcc_bootstrap_linux-64-9.5.0-hf039093_10/x86_64-conda-linux-gnu/lib/libstdc++.so.6.0.28
    ./gcc_impl_linux-64-9.5.0-h6c5bc03_16/x86_64-conda-linux-gnu/lib/libstdc++.so.6.0.28

    is libstdcxx-ng even necessary in that case? I'd assume that gxx_impl will be the one that is used in the end?

I can already tell you that the relevant line is make -C $CHOST/libstdc++-v3/python prefix=${PREFIX} install in install-g++.sh, but didn't dig further. If gcc used the library from libstdcxx-ng, at least the relative path would be correct, but if it used the one from gxx_impl, it would be missing the x86_64-conda-linux-gnu/ prefix.

isuruf commented 2 years ago

It seems like gxx_impl_linux-64 9.5.0 should work fine. Can you try updating gxx_impl_linux-64 in your env?

upsj commented 2 years ago

Not sure what you're saying - I built gxx_impl_linux-64 9.5.0, and it contains the correct file, but in the wrong location. I'll see if I can fix it. In general, putting the file into auto-load regardless of whether we're cross-compiling or not seems safe, since the (not binary, but structural) layout of the types is pretty much architecture-independent.

mdemoret-nv commented 1 year ago

@upsj Were you able to make any more progress on this? This issue has been bugging me for a while now. Your write up helped me understand what was going on but I haven't been able to figure out a good workaround for this.

mvelbaum commented 2 months ago

@isuruf can you please explain why this code is commented out? https://github.com/conda-forge/ctng-compilers-feedstock/blob/54154d3669138f9e9bb879889c7e930d1634e77b/recipe/install-g%2B%2B.sh#L31-L33

Without the *-gdb.py in the right place you don't get pretty-printing for libstdc++ symbols in debuggers. I see there is a file under $CONDA_PREFIX/lib/-gdb.py and I'm not sure how it gets there.