我試圖理解ldd --version和ldd -v a.out
我有下面的簡單程式
#include <iostream>
#include <string>
#include <cstring>
int main()
{
std::cout << "Hello world" << std::endl;
std::string a = "Test string";
char b[15] = {};
memcpy(b, a.c_str(), 15);
std::cout << b << std::endl;
return 0;
}
我用以下命令編譯它
g --std=c 17 test.cpp
我想知道當我運行 say 時這個程式將使用哪個 glibc 版本memcpy。
ldd --version在這個系統上的輸出是:
ldd --version
ldd (Ubuntu GLIBC 2.31-0ubuntu9.2) 2.31
Copyright (C) 2020 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.
的輸出ldd -v a.out是
ldd -v a.out
linux-vdso.so.1 (0x00007ffe7d3f3000)
libstdc .so.6 => /usr/lib/x86_64-linux-gnu/libstdc .so.6 (0x00007f050bb2f000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f050bb14000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f050b922000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f050b7d3000)
/lib64/ld-linux-x86-64.so.2 (0x00007f050bd3a000)
Version information:
./a.out:
libgcc_s.so.1 (GCC_3.0) => /lib/x86_64-linux-gnu/libgcc_s.so.1
libc.so.6 (GLIBC_2.4) => /lib/x86_64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.2.5) => /lib/x86_64-linux-gnu/libc.so.6
libstdc .so.6 (GLIBCXX_3.4.21) => /usr/lib/x86_64-linux-gnu/libstdc .so.6
libstdc .so.6 (CXXABI_1.3) => /usr/lib/x86_64-linux-gnu/libstdc .so.6
libstdc .so.6 (GLIBCXX_3.4) => /usr/lib/x86_64-linux-gnu/libstdc .so.6
/usr/lib/x86_64-linux-gnu/libstdc .so.6:
libm.so.6 (GLIBC_2.2.5) => /lib/x86_64-linux-gnu/libm.so.6
ld-linux-x86-64.so.2 (GLIBC_2.3) => /lib64/ld-linux-x86-64.so.2
libgcc_s.so.1 (GCC_4.2.0) => /lib/x86_64-linux-gnu/libgcc_s.so.1
libgcc_s.so.1 (GCC_3.4) => /lib/x86_64-linux-gnu/libgcc_s.so.1
libgcc_s.so.1 (GCC_3.3) => /lib/x86_64-linux-gnu/libgcc_s.so.1
libgcc_s.so.1 (GCC_3.0) => /lib/x86_64-linux-gnu/libgcc_s.so.1
libc.so.6 (GLIBC_2.14) => /lib/x86_64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.6) => /lib/x86_64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.4) => /lib/x86_64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.18) => /lib/x86_64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.16) => /lib/x86_64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.3) => /lib/x86_64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.3.4) => /lib/x86_64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.17) => /lib/x86_64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.3.2) => /lib/x86_64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.2.5) => /lib/x86_64-linux-gnu/libc.so.6
/lib/x86_64-linux-gnu/libgcc_s.so.1:
libc.so.6 (GLIBC_2.14) => /lib/x86_64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.2.5) => /lib/x86_64-linux-gnu/libc.so.6
/lib/x86_64-linux-gnu/libc.so.6:
ld-linux-x86-64.so.2 (GLIBC_2.3) => /lib64/ld-linux-x86-64.so.2
ld-linux-x86-64.so.2 (GLIBC_PRIVATE) => /lib64/ld-linux-x86-64.so.2
/lib/x86_64-linux-gnu/libm.so.6:
ld-linux-x86-64.so.2 (GLIBC_PRIVATE) => /lib64/ld-linux-x86-64.so.2
libc.so.6 (GLIBC_2.4) => /lib/x86_64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.2.5) => /lib/x86_64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_PRIVATE) => /lib/x86_64-linux-gnu/libc.so.6
我不明白的是,如果ldd --version說我有可用的 GLIBC 2.31 版,那么為什么我的可執行檔案 ldd 輸出說GLIBC_2.4和GLIBC_2.2.5a.out。
理解這一點的正確方法是什么?
如果我在具有舊版本 libc.so 的系統上編譯二進制檔案(假設 GLIBC 的最高版本為 2.17),然后在具有新版本 libc.so 的系統上運行二進制檔案(假設有最高版本)會發生什么GLIBC 為 2.31)?
謝謝
uj5u.com熱心網友回復:
您應該閱讀此答案,并查看readelf -V a.out.
鏈接程式時,它會記錄鏈接時使用的(當前)符號版本。
您的程式使用的許多符號自 eg 以來 都沒有改變GLIBC_2.2.5,所以ldd說:您至少需要版本GLIBC_2.2.5(對于這些符號)。一些使用的符號都在改變GLIBC-2.16,GLIBC-2.17并且GLIBC-2.18,所以ldd說,你需要這些為好。
如果我在具有舊版本 libc.so 的系統上編譯二進制檔案(假設 GLIBC 的最高版本為 2.17),然后在具有新版本 libc.so 的系統上運行二進制檔案(假設有最高版本)會發生什么GLIBC 為 2.31)?
記錄的符號(編碼為a.out)將全部是GLIBC_2.17或更舊的,并且程式將在較新的系統上運行良好,因為 GLIBC 保證向后兼容性(建立在較舊系統上的程式繼續在較新的系統上運行良好)。
但是如果你做相反的事情——建立在一個GLIBC-2.31系統上并試圖在一個系統上運行程式GLIBC-2.17,它可能(也可能不會,取決于它實際使用的符號)失敗。
在您提供的示例中,所需的最高版本GLIBC是GLIBC_2.18. 因此,這個特殊的a.out在一個GLIBC-2.18或更新的系統上可以正常作業,但在GLIBC-2.17或更舊的系統上會失敗。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/386154.html
