के लिए लाइब्रेरी पथ ऑर्डर मुझे अपने सिस्टम (2.18
बनाम 2.15
बनाम) के मुकाबले एक वैकल्पिक glibc
संस्करण का उपयोग करने की आवश्यकता है। कई संबंधित मुद्दों को here और here शामिल किया गया है।वैकल्पिक ग्लिब गतिशील लिंकर (ld.so)
मैं नए गतिशील लिंकर (ld-2.18.so
) है कि नए libc
(libc-2.18.so
) तो पुराने libc
(libc-2.15.so
) से आगे पाया जाता है के पुस्तकालय पथ की स्थापना: विशिष्ट प्रश्न मैं यहाँ पूछ रहा हूँ पीछा कर रहा है। हालांकि, जब मैं नए ld
के साथ प्रोग्राम चलाने की कोशिश करता हूं, तो libc
का पुराना संस्करण उठाया जाता है, जिससे SEGV
उत्पन्न होता है। ऐसा क्यों हो रहा है?
नोट: मुझे पता है कि इसे संकलित समय पर --rpath
या LD_LIBRARY_PATH
रन टाइम पर उपयोग करके तय किया जा सकता है। हालांकि, मैं अभी भी समझना चाहूंगा कि इनमें से एक को अभी भी क्यों जरूरी है।
विवरण का पालन करें:
मैं glibc-2.18
डाउनलोड किया है और /opt/glibc-2.18
पर इसे बनाया गया। डिफ़ॉल्ट रूप से, फ़ाइल /opt/glibc-2.18/etc/ld.so.conf
गुम है। मैंने इसे बनाया है, और नए glibc
के लाइब्रेरी कैश को निम्नानुसार अपडेट किया है। मैं जोर देते हैं कि: नई libc
वर्ष libc
से पहले पाया जाता है: तो फिर
$ cat /opt/glibc-2.18/etc/ld.so.conf
/opt/glibc-2.18/lib
/usr/local/lib
/lib/x86_64-linux-gnu
/usr/lib/x86_64-linux-gnu
/usr/lib/x86_64-linux-gnu/mesa
/lib
/usr/lib
$ /opt/glibc-2.18/sbin/ldconfig -v |& grep -E '^[^'$'\t'']|libc\.'
/opt/glibc-2.18/sbin/ldconfig: Path `/opt/glibc-2.18/lib' given more than once
/opt/glibc-2.18/sbin/ldconfig: Can't stat /opt/glibc-2.18/lib64: No such file or directory
/opt/glibc-2.18/sbin/ldconfig: Can't stat /opt/glibc-2.18/libx32: No such file or directory
/opt/glibc-2.18/lib:
libc.so.6 -> libc-2.18.so
/usr/local/lib:
/lib/x86_64-linux-gnu:
libc.so.6 -> libc-2.15.so
/usr/lib/x86_64-linux-gnu:
/usr/lib/x86_64-linux-gnu/mesa:
/lib:
/usr/lib:
, मैं एक साधारण सी कार्यक्रम बनाया:
$ cat <<EOF >a.c
> #include <stdio.h>
> int main()
> {
> fprintf(stdout, "ok\n");
> return 0;
> }
> EOF
$ g++ a.c
$ file a.out
a.out: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=0x43b8484e3910072375d68418cb6327478266c0e9, not stripped
$ ldd a.out
linux-vdso.so.1 => (0x00007fffd7ffe000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa7c47bd000)
/lib64/ld-linux-x86-64.so.2 (0x00007fa7c4b9b000)
$ readelf -a a.out | grep lib
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
000000601000 000100000007 R_X86_64_JUMP_SLO 0000000000000000 __libc_start_main + 0
1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND [email protected]_2.2.5 (2)
46: 00000000004005f0 2 FUNC GLOBAL DEFAULT 13 __libc_csu_fini
52: 0000000000000000 0 FUNC GLOBAL DEFAULT UND [email protected]@GLIBC_
57: 0000000000400560 137 FUNC GLOBAL DEFAULT 13 __libc_csu_init
000000: Version: 1 File: libc.so.6 Cnt: 1
$ objdump -x a.out | grep -A3 Version
Version References:
required from libc.so.6:
0x09691a75 0x00 02 GLIBC_2.2.5
जैसा कि ऊपर देखा, इस कार्यक्रम वर्ष ld
कठिन है अंदर कोडित मैं इसे नए ld
के साथ मजबूती से चला सकता हूं, और मुझे उपयोग होने के लिए नए ld
के पथ की उम्मीद है (आप नया ld.so.cache
खोला जा रहा है)। हालांकि, किसी कारण से मैं समझने की कोशिश कर रहा हूँ, वर्ष libc
नई libc
से पहले पाया जाता है, एक SEGV पैदा:
$ /opt/glibc-2.18/lib/ld-2.18.so ./a.out
Segmentation fault (core dumped)
$ strace /opt/glibc-2.18/lib/ld-2.18.so ./a.out |& grep open
open("./a.out", O_RDONLY|O_CLOEXEC) = 3
open("/opt/glibc-2.18/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
मैं भी नए पुस्तकालय के साथ संकलन और बेक-इन नई ld
कर सकते हैं इस प्रकार है:
$ g++ -L/opt/glibc-2.18/lib -Wl,--dynamic-linker=/opt/glibc-2.18/lib/ld-2.18.so a.c -o a.2.18.out
$ file a.2.18.out
a.2.18.out: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=0x25ab43f3d29b49fa21385a15e43325e9fb904e81, not stripped
$ ldd a.2.18.out
linux-vdso.so.1 => (0x00007fffa68da000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f9df5cbe000)
/opt/glibc-2.18/lib/ld-2.18.so => /lib64/ld-linux-x86-64.so.2 (0x00007f9df609c000)
$ readelf -a a.2.18.out | grep lib
[Requesting program interpreter: /opt/glibc-2.18/lib/ld-2.18.so]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
000000601000 000100000007 R_X86_64_JUMP_SLO 0000000000000000 __libc_start_main + 0
1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND [email protected]_2.2.5 (2)
54: 0000000000400600 2 FUNC GLOBAL DEFAULT 13 __libc_csu_fini
60: 0000000000000000 0 FUNC GLOBAL DEFAULT UND [email protected]@GLIBC_
65: 0000000000400570 137 FUNC GLOBAL DEFAULT 13 __libc_csu_init
000000: Version: 1 File: libc.so.6 Cnt: 1
$ objdump -x a.2.18.out | grep -A3 Version
Version References:
required from libc.so.6:
0x09691a75 0x00 02 GLIBC_2.2.5
फिर भी, अगर मैं नए कार्यक्रम एक ही बात होता है चलाने का प्रयास, वर्ष libc
नई libc
के स्थान पर प्रयोग किया जा रहा है:
$ ./a.2.18.out
Segmentation fault (core dumped)
$ strace ./a.2.18.out |& grep open
open("/opt/glibc-2.18/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
या तो निष्पादन के साथ
, यह निर्दिष्ट LD_LIBRARY_PATH=/opt/glibc-2.18/lib
यह काम करता है। हालांकि, मेरा प्रश्न यह है कि अभी भी इसकी आवश्यकता क्यों है, क्योंकि ld
के नए libc
से पहले नए libc
को चुनने के लिए शुरुआत में नया ld
का मार्ग कॉन्फ़िगर किया गया है।