###### tags: `Linux-command` # Install glibc in centos 7 in manually > 如果嫌麻煩可以直接看[Take Away](https://hackmd.io/EolJ3dfmQe-ILc6h1VGD5g#Take-Away) ## 前言 想必大家都有嘗試著從github下載別人編好的release binary的經驗。 但是往往別人使用的glibc的版本都比自己的電腦擁有的glibc版本還要高。 這時候就會看到以下惱人的訊息。 ``` linux ./bytehound/bytehound: /lib64/libm.so.6: version `GLIBC_2.27' not found (required by ./bytehound/bytehound) ./bytehound/bytehound: /lib64/libm.so.6: version `GLIBC_2.29' not found (required by ./bytehound/bytehound) ./bytehound/bytehound: /lib64/libc.so.6: version `GLIBC_2.25' not found (required by ./bytehound/bytehound) ./bytehound/bytehound: /lib64/libc.so.6: version `GLIBC_2.28' not found (required by ./bytehound/bytehound) ./bytehound/bytehound: /lib64/libc.so.6: version `GLIBC_2.18' not found (required by ./bytehound/bytehound) ``` 這時候該怎麼辦呢,當然是更新我們的glibc呀! 但是,使用公司的VM又沒有更新底層的權力,這時候就要學會怎麼在local端安裝了! ## glibc installation 首先,先進入glibc下載用的ftp server。 https://ftp.gnu.org/gnu/glibc/ 這次我們使用glibc 2.30為例子 https://ftp.gnu.org/gnu/glibc/glibc-2.30.tar.gz 一開始我是參考這篇文章來安裝 [Centos 7 升级 Glibc-2.28](https://cloud.tencent.com/developer/article/2021784),中途我把`--with-headers=/usr/include --with-binutils=/usr/bin`這兩個flag拿掉,因為我不想使用/usr提供的東西,並且加上--disable-werror,來忽略一些不必要的warning。而以下就是完整的指令 ``` linux wget https://ftp.gnu.org/gnu/glibc/glibc-2.30.tar.gz tar zxvf glibc-2.30.tar.gz mkdir build && mkdir release cd build ../glibc-2.30/configure --disable-profile --enable-add-ons --prefix=$(readlink -f ../release) --disable-werror make -j && make install ``` 執行完以後,release的資料夾內就會有所有的東西了。 ## 開始DEB....UG > 為了方便撰寫,以下出現的\<RELEASE\>都替換成上一段的release資料夾 如果上述完成後就結束的話,那就太簡單了我根本不用寫這篇文來記錄我debug過程。 第一,我想要一勞永逸的直接使用glibc,所以我直接把glibc的路徑設到LD_LIBRARY_PATH上面。 `export LD_LIBRARY_PATH=<RELEASE>/lib:${LD_LIBRARY_PATH}` 然後就...崩! 我的prompt怎麼不見了???? ls一下好了...?????? 怎麼**segmentation fault**了。 查了一下,我太廢了也找不到解答(如果有人知道的話請跟我說QQ),但是有依稀看到一些stackoverflow的解答是說,glibc太底層了,不要直接把path設過去,可能會使得機器跑不起來。 既然都有人這樣說了,那我不做了。我只在需要高版本glibc的binary去使用新版的ld就好 所以有了以下的指令 ``` linux <RELEASE>/lib/ld-linux-x86-64.so.2 /bin/ls # Oops, there is a error when loading shared library /bin/ls: error while loading shared libraries: libselinux.so.1: cannot open shared object file: No such file or directory ``` 居然找不到libselinux.so.1,我們用ldd來看看他原本在哪裡。 ``` linux ldd /bin/ls ... libselinux.so.1 => /lib64/libselinux.so.1 (0x00007ffff7bb4000) ... ``` 奇怪,明明是在/lib64這麼顯眼的地方為什麼會找不到呢。在一陣亂google後發現ld-linux-x86-64.so.2有一個flag可以設定library-path ``` linux <RELEASE>/lib/ld-linux-x86-64.so.2 --library-path /lib64 /bin/ls ``` 這個指令貌似可以了。但是當我測試回我想使用的binary時又出問題了。 ``` linux <RELEASE>/lib/ld-linux-x86-64.so.2 --library-path /lib64 ./bytehound ./bytehound: /lib64/libm.so.6: version `GLIBC_2.27' not found (required by ./bytehound) ./bytehound: /lib64/libm.so.6: version `GLIBC_2.29' not found (required by ./bytehound) ./bytehound: /lib64/libc.so.6: version `GLIBC_2.25' not found (required by ./bytehound) ./bytehound: /lib64/libc.so.6: version `GLIBC_2.28' not found (required by ./bytehound) ./bytehound: /lib64/libc.so.6: version `GLIBC_2.18' not found (required by ./bytehound) ``` 怎麼又不行了呢??????? 這時我猜測使用這個flag後,PATH可能會被重製,所以我嘗試把glibc2.30的lib加進去library-path內 ``` <RELEASE>/lib/ld-linux-x86-64.so.2 --library-path <RELEASE>/lib:/lib64 ./bytehound ``` Oh! yes! 這次可以了,我看到了出口的曙光了。 But,人生就是有這個But。正當我開開心心的想用bytehound去替我們公司的產品做memory profiler時又出事了。 ``` linux export MEMORY_PROFILER=warn LD_PRELOAD=<bytehound installation>/libbytehound.so <RELEASE>/lib/ld-linux-x86-64.so.2 --library-path <RELEASE>/lib:/lib64 <executable> # Oops error while loading shared libraries: libstdc++: cannot open shared object file: No such file or directory ``` 原來是我們公司產品有link到自己編譯的libstdc++,而library-path flag沒有找到的緣故。 那這簡單,就跟上面的方法一樣,把path加進去。 但此時會發現根本沒完沒了,後來我嘗試把現有的LD_LIBRARY_PATH直接加進中間會發生甚麼事情。 ```linux export MEMORY_PROFILER=warn LD_PRELOAD=<bytehound installation>/libbytehound.so <RELEASE>/lib/ld-linux-x86-64.so.2 --library-path <RELEASE>/lib:${LD_LIBRARY_PATH}:/lib64 <executable> ``` 這樣就可以了! 以後我們就可以用類似的方法來執行這些高版本glibc的執行檔了。 下面是我之後簡單包裝的wrapper ``` bash #!/bin/bash library_path="<RELEASE>/lib:${LD_LIBRARY_PATH}:/lib64" <RELEASE>/lib/ld-linux-x86-64.so.2 --library-path ${library_path} $@ ``` ## Take Away * installtion * ``` linux wget https://ftp.gnu.org/gnu/glibc/glibc-2.30.tar.gz tar zxvf glibc-2.30.tar.gz mkdir build && mkdir release cd build ../glibc-2.30/configure --disable-profile --enable-add-ons -- prefix=$(readlink -f ../release) --disable-werror make -j && make install ``` * wrap the library_path * ``` bash #!/bin/bash library_path="<RELEASE>/lib:${LD_LIBRARY_PATH}:/lib64" <RELEASE>/lib/ld-linux-x86-64.so.2 --library-path ${library_path} $@ ```