2013-12-13 4 views
7

के लिए लाइब्रेरी पथ ऑर्डर मुझे अपने सिस्टम (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 का मार्ग कॉन्फ़िगर किया गया है।

उत्तर

5

मुझे यह मिला, यह मुद्दा ओएस एबीआई संस्करण के साथ था।

$ file /lib/x86_64-linux-gnu/libc-2.15.so | grep -o "for GNU/Linux [0-9.]*" 
for GNU/Linux 2.6.24 

glibc--prefix अलावा कुछ भी नहीं के साथ विन्यस्त किया जाता है, यह एक ABI संस्करण छोटे (के साथ डिफ़ॉल्ट रूप से बनाता है !!: यह इस तरह के रूप संख्या file ने संकेत दिया है,) (मेरे मामले में, 2.6.16) सिस्टम पर डिफ़ॉल्ट से (2.6.24)। तो libc-2.18 में एबीआई संस्करण libc-2.15 से छोटा है।

जब ldconfig अलग ABI संख्या के साथ libc.so.6 के 2 संस्करण पाता है, यह उन्हें ld.so.cacheमें ABI संख्या उतरते के क्रम में, उपस्थिति के क्रम में नहीं देता है। यह उनके स्थानों को स्वैप करके, कैश का पुनर्निर्माण करके (ldconfig के साथ), और कैश सामग्री सूचीबद्ध कर सकते हैं (ldconfig -p के साथ)। केवल जब 2 libc.so.6 फ़ाइलों में एक ही एबीआई संस्करण होता है, तो क्या उन्हें उपस्थिति के क्रम में कैश में रखा जाता है।

का विन्यास glibc--enable-kernel=2.6.24 के साथ, की आवश्यकता के बिना एक स्पष्ट --rpath या LD_LIBRARY_PATH के लिए प्रणाली, जो बारी में प्रश्न बयान में संकल्प समस्याओं का समाधान करता के रूप में ही ABI संस्करण का उपयोग करने का कारण बनता है।

संबंधित मुद्दे