मेरा सिस्टम किस सी लाइब्रेरी संस्करण का उपयोग करता है?


43

मैं यह कैसे सुनिश्चित कर सकता हूं कि मेरे सिस्टम का उपयोग करने वाले उपयोगकर्ता लाइब्रेरी का उपयोग करें? इस जानकारी की आवश्यकता के संभावित कारणों में शामिल हैं:

  • एक विशाल स्रोत पैकेज है जिसे मैं डाउनलोड करने पर विचार कर रहा हूं जो मुझे यकीन है कि उचित जांच करेगा और एक मिनिनम लाइब्रेरी संस्करण को सूचीबद्ध करेगा, लेकिन मैं पहले जांच करके खुद को संभावित परेशानी से बचाऊंगा अगर यह काम करेगा।

  • मैं एबीआई संगतता के बारे में चिंतित हूं, कुछ तीसरे पक्ष के बायनेरिज़ के साथ जो मैं सिस्टम के पैकेज प्रबंधन प्रणाली के बाहर स्थापित करना चाहता हूं।

  • मेरे पास एक स्रोत पैकेज है जो दस्तावेज़ीकरण में मेरे सिस्टम के लाइब्रेरी के न्यूनतम संस्करण की आवश्यकता का उल्लेख करता है, लेकिन निर्माण प्रक्रिया किसी भी चेक का प्रदर्शन नहीं करती है।

  • मैं एक विशिष्ट प्रणाली को लक्षित करने वाले क्रॉस-कंपाइलर का निर्माण कर रहा हूं और आगे संगतता समस्याओं का जोखिम नहीं उठाना चाहता ।


क्यों नहीं यह कोशिश करो और देखो। मुझे नहीं पता कि संस्करण आपको सब कुछ बताता है; पैच के बारे में क्या? या एबीआई को बदलने के बारे में सावधानी बरत रहे हैं? मुद्दा यह नहीं है कि निर्यात किए गए प्रतीकों को हल किया जाता है, या ऐसा कुछ?
फहीम मीठा

अच्छा जवाब है, लेकिन कोई मैक पर ऐसा करने के लिए कैसे संबोधित करता है, जहां कोई नहीं है ldd। मुझे यकीन नहीं है कि अगर otool --versionवही जानकारी दी जा सकती है।
संदिग्ध

@dubiousjim कोई; सिर्फ मैं नहीं, क्योंकि मैं मैक उपयोगकर्ता नहीं हूं। यहाँ के आसपास आपको विशेष रूप से उस बारे में पूछना पड़ सकता है - इस मुद्दे का हिस्सा शायद लोग आमतौर पर OSX पर सादे सी का उपयोग नहीं करते हैं? लेकिन मुझे यकीन है कि एक नियमित व्यक्ति होगा जो जानता है। आप चैट में इसके लिए एक लिंक भी पोस्ट कर सकते हैं और देख सकते हैं कि क्या होता है, लेकिन शायद एक नया, अधिक विशिष्ट प्रश्न बेहतर होगा।
गोल्डीलॉक्स

जवाबों:


50

GNU / Linux सिस्टम आमतौर पर या तो glibc (Fedora / Redhat परिवार, Arch) या उसके करीबी चचेरे भाई, eglibc (Debian / Ubuntu परिवार) का उपयोग करते हैं; चूंकि अब एग्लिबेक को वापस ग्लिबेक में विलय किया जा रहा है ( देखें ईजीएलआईबीसी 2.19 शाखा "समाचार" के तहत बनाया गया ), निकट भविष्य में वे सभी फिर से ग्लिबेक हो जाएंगे।

सटीक संस्करण की जांच करने का सबसे आसान तरीका यह पूछना है lddकि सी लाइब्रेरी के साथ कौन से जहाज हैं।

फेडोरा 20 पर:

> ldd --version
ldd (GNU libc) 2.18

वह ग्लिब 2.18 है।

रास्पियन पर (ARMv6 ब्रॉडकॉम SoC के लिए डेबियन 7 पोर्ट):

> ldd --version
ldd (Debian EGLIBC 2.13-38+rpi2) 2.13

वह २.१३ है।

यदि किसी भी कारण से आपने कुछ हिस्सों को मिलाया और मिलान किया है या अन्यथा निश्चित नहीं हैं ldd, तो आप सीधे सी लाइब्रेरी को क्वेरी कर सकते हैं।

> whereis libc.so
libc: /usr/lib64/libc.a /usr/lib64/libc.so /usr/share/man/man7/libc.7.gz

उनमें से कोई भी निष्पादन योग्य नहीं है, लेकिन वे इस बारे में एक सुराग प्रदान करते हैं कि किसी को कहां खोजना है।

> $(find /usr/lib64/ -executable -name "*libc.so*") --version
GNU C Library (GNU libc) stable release version 2.18, by Roland McGrath et al.

हालांकि, यह जरूरी नहीं है कि यह इतना आसान है, क्योंकि सी लाइब्रेरी को कहीं नहीं रहना है whereis

> whereis libc.so
libc: /usr/share/man/man7/libc.7.gz

दुर्भाग्य से, मैन पेज एक संस्करण संख्या प्रदान नहीं करता है। lddअभी भी काम में आता है, क्योंकि सिस्टम पर किसी भी काम, गतिशील रूप से जुड़े निष्पादन योग्य (जैसे, लगभग सब कुछ /usr/bin) सी लाइब्रेरी से लिंक होगा।

> ldd /usr/bin/touch
    /usr/lib/arm-linux-gnueabihf/libcofi_rpi.so (0xb6eed000)
    librt.so.1 => /lib/arm-linux-gnueabihf/librt.so.1 (0xb6ed0000)
    libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0xb6da1000)
    /lib/ld-linux-armhf.so.3 (0xb6efb000)
    libpthread.so.0 => /lib/arm-linux-gnueabihf/libpthread.so.0 (0xb6d82000)

libc.so.6 तीसरी लाइन पर है।

> /lib/arm-linux-gnueabihf/libc.so.6 --version
GNU C Library (Debian EGLIBC 2.13-38+rpi2) stable release version 2.13, by Roland McGrath et al.

जीएनयू / लिनक्स सिस्टम "सामान्य" क्या बनाता है? मसल के उपयोग से वितरण के बारे में क्या ?
इलियट फ्रिस्क

1
@ElliottFrisch जीएनयू / लिनक्स पर लागू करने का इरादा था, "सामान्य जीएनयू / लिनक्स" (विशेषण, संज्ञा) के रूप में, क्योंकि वहाँ हो सकता है (हैं, मुझे यकीन है) सिस्टम जो (ई) ग्लास का उपयोग नहीं करते हैं लेकिन करते हैं बाकी GNU स्टैक (बैश, बिन्यूटिल्स इत्यादि) का उपयोग करें। मैं उन "असामान्य" GNU / Linux सिस्टम पर विचार करूंगा। लेकिन मैंने "सामान्य" हटा दिया है और इसे "जीएनयू / लिनक्स सिस्टम आमतौर पर उपयोग करता हूं ..." में बदल दिया । नोट I ने जानबूझकर प्रश्न खुला WRT OS बारीकियों को छोड़ दिया है (कोई linux या GNU या glibc टैग नहीं है), इसलिए यदि आप U & L के लिए उपयुक्त किसी प्रणाली के संबंध में उत्तर जोड़ना चाहते हैं, तो कृपया करें।
गोल्डीलॉक्स

1
आपके द्वारा दिखाए जाने के बाद मैंने इसे ढूंढ लिया और मैंने संस्करण को छोड़ दिया, इसने उपलब्ध एक्सटेंशनों को भी मुद्रित किया! (मेरे मामले में स्टब्स, क्रिप्ट, लिबिडन, देशी थ्रेड्स और बाइंड) और ABI: libc ABIs: UNIQUE IFUNC का उल्लेख किया गया है।

डेबियन /lib/`uname -m`*पथ का उपयोग करता है। तो पोर्टेबल तरीका होगा: find /lib/`uname -m`* /usr/lib* -executable -name "*libc.so*" | xargs --version। अच्छी व्याख्या के लिए धन्यवाद।
pevik

@ सात्विक: गलत, बांह पर यह /lib/arm-linux-gnueabihf/libc.so.6, और नहीं /lib/armv7l/libc.so.6
Quandary

14

एक प्रणाली वास्तव में एक सी लाइब्रेरी तक सीमित नहीं है। हालांकि, अधिकांश, मुख्य रूप से केवल एक का उपयोग करते हैं, जो कि डिफ़ॉल्ट कंपाइलर का उपयोग करने वाला भी होगा। और जब से आप संकलन करने के लिए स्रोत कोड डाउनलोड कर रहे हैं, वह वही है जिससे आप चिंतित हैं।

एक तुच्छ कार्यक्रम से शुरू करें:

#include <stdio.h>
int main() {
    printf("Hello, world\n");
    return 0;
}

संकलक का उपयोग करके इसे संकलित करें जो आप स्रोत कोड के लिए उपयोग करने जा रहे हैं, फिर lddयह जानने के लिए उपयोग करें कि C लाइब्रेरी कहाँ है:

$ ldd ./libc-test 
        linux-vdso.so.1 (0x00007fff2e5fe000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f8c8ad98000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f8c8b171000)

अब आपके पास C लाइब्रेरी का रास्ता है। आप पैकेज खोजने के लिए अपने पैकेज मैनेजर में इसे देख सकते हैं (उदाहरण के लिए, dpkg -S /lib/x86_64-linux-gnu/libc.so.6या rpm -q -f /lib/x86_64-linux-gnu/libc.so.6)।

कम से कम eglibc / glibc के मामले में, आप इसे चला सकते हैं:

$ /lib/x86_64-linux-gnu/libc.so.6  
GNU C Library (Debian EGLIBC 2.18-4) stable release version 2.18, by Roland McGrath et al.
Copyright (C) 2013 Free Software Foundation, Inc.

अंत में, आप देख सकते हैं कि क्या आप संस्करण परिभाषा अनुभाग objdump -p /lib/x86_64-linux-gnu/libc.so.6में देख कर सुराग प्राप्त कर सकते हैं :

Version definitions:
1 0x01 0x0865f4e6 libc.so.6
2 0x00 0x09691a75 GLIBC_2.2.5
3 0x00 0x09691a76 GLIBC_2.2.6
21 0x00 0x06969197 GLIBC_2.17
        GLIBC_2.16 
22 0x00 0x06969198 GLIBC_2.18
        GLIBC_2.17 
23 0x00 0x0963cf85 GLIBC_PRIVATE
        GLIBC_2.18 

ध्यान दें कि GLIBC_2.18 प्रतीक में सूचीबद्ध प्रतीकों के बीच सबसे हाल का संस्करण संख्या क्या है, और पुस्तकालय संस्करण वास्तव में 2.18 है। हालांकि यह ईगलिबेक है (इसका उद्देश्य ग्लिबैक 2.18 के साथ द्विआधारी-संगत होना है, इसलिए यह समान प्रतीक संस्करणों का उपयोग करता है)।

आप stringsइसके बारे में कुछ जानने के लिए उपयोग करने का भी प्रयास कर सकते हैं । आप एक लंबी न्यूनतम लंबाई निर्दिष्ट करना चाहते हैं ( -n), या कुछ खोजने के लिए grep का उपयोग करें:

$ strings  /lib/x86_64-linux-gnu/libc.so.6 | grep 'version [0-9]'
$ strings  /lib/x86_64-linux-gnu/libc.so.6 | grep -iC1 'copyright'

दोनों इस eglibc के लिए काम करते हैं।

नोट: डेबियन पैकेज उपयोगिता हुड के तहत dpkg-shlibdepsउपयोग objdumpकरती है, साथ ही बिल्ड समय में बाइनरी डेबियन पैकेजों द्वारा आवश्यक निर्भरता के न्यूनतम संस्करणों को निर्धारित करने के लिए डेबियन लाइब्रेरी पैकेजों में संग्रहीत प्रतीक सूचना के साथ। मूल रूप से, यह बाइनरी डेबियन पैकेज द्वारा निर्यात किए गए प्रतीकों को देखता है, और फिर उन प्रतीकों वाले पुस्तकालयों के न्यूनतम संस्करणों को ढूंढता है।


9

स्पष्ट जवाब, हालांकि सबसे व्यापक नहीं है, अपने पैकेज मैनेजर की जांच करना है, जैसे

rpm -qi glibc
dpkg -l libc6

(अफसोस की बात है, glibc के पास एक pkconfig .pcफ़ाइल नहीं है , इसलिए pkgconfig --modversion glibcवह एक गैर-धावक है।) @ Gnouc का उत्कृष्ट getconfसुझाव भी देखें ।

सरलतम मामला, gcc + glibc के साथ, और जो मैं ज्यादातर उपयोग करता हूं, वह केवल निष्पादित करने के लिए है libc.so, जैसा कि यहां कुछ अन्य उत्तरों में उल्लिखित है। किसी भी तर्क को पारित करने की आवश्यकता नहीं है, यह डिफ़ॉल्ट रूप से इसके संस्करण को आउटपुट करता है। यह glibc-2.1 (glibc-2.0 seg-faults) के रूप में वापस काम करता है, हालांकि वापस तो आप glibcbugसंस्करण की पुष्टि करने के लिए अब (अब सेवानिवृत्त) स्क्रिप्ट की जांच कर सकते हैं । इस विधि भी हाल (> 0.9.15) के संस्करणों के साथ काम करता musl-libc (जो सिर्फ 1.0 आज, 20 मार्च चला गया)। यह uClibc के साथ काम नहीं करता है, यह segfaults है।

यह बताने का एक सरल तरीका कि आपका क्या gccकरने जा रहा है:

#include <gnu/libc-version.h>
#include <stdio.h>
int main(int argc, char *argv[]) {
    printf("%s %s\n",gnu_get_libc_version(),gnu_get_libc_release());
    printf("glibc v%i %i.%i\n",__GNU_LIBRARY__,__GLIBC__,__GLIBC_MINOR__);
    return 0;
}

(glibc के साथ, <stdio.h>जिसमें <features.h>प्रासंगिक GLIBC मैक्रो को परिभाषित किया गया है, आपको <gnu/libc-version.h>फ़ंक्शन घोषणाओं की आवश्यकता है।)

यह अधिक जटिल मामलों (एकाधिक libc, और / या कई संकलक) को पकड़ता है, यह मानते हुए कि आप सही संकलक (और झंडे) का उपयोग कर रहे हैं। (मुझे संदेह है कि यह ईगलिबेक और ग्लिबक के बीच उचित अंतर नहीं करेगा।)

यदि आप निश्चित हैं कि आप glibc (या eglibc) का उपयोग कर रहे हैं तो ldसंस्करण की पुष्टि भी करेगा (क्षमा करें, यह सही नहीं है)।

यदि __GNU_LIBRARY__परिभाषित नहीं किया गया है तो आपको त्रुटियां मिलेंगी, तो यह योजना बी का समय है।

gcc -dumpmachineमदद कर सकते हैं, जैसे uclibc के लिए इसका -uclibcप्रत्यय हो सकता है, जैसा कि हो सकता है gcc -dumpspecs | grep dynamic-linker। यह एबीआई को भी प्रभावित कर सकता है।

gcc -print-file-name=libc.soआपको बताएगा कि कंपाइलर किस फाइल को " -lc" के लिए उपयोग करेगा , यह निश्चित रूप से आपके जीसीसी इंस्टॉलेशन के भीतर एक लिंकर-स्क्रिप्ट है, जिसे आप इसे सादे पाठ के रूप में पढ़ सकते हैं। यही सही रास्ता दिखाएगा libc.so। यह भी काम करेगा यदि आप झंडे की तरह गुजर रहे हैं -m32या -m64

घटना में आप यूक्लिब का उपयोग कर रहे हैं (जैसा कि OpenWRT और अधिक द्वारा उपयोग किया जाता है), यह परिभाषित करता है __UCLIBC_MAJOR__, __UCLIBC_MINOR__और __UCLIBC_SUBLEVEL__साथ ही __UCLIBC__में <features.h>, इसलिए यह आसानी से उपरोक्त सी कोड स्निपेट पर एक मामूली बदलाव का उपयोग करके पता लगाया जाता है। अनुकूलता के हित में, UClibc GNU / GLIBC मैक्रोज़ को भी परिभाषित कर सकता है जैसा कि ऊपर बताया गया है, यह वर्तमान में glibc-2.2 होने का दिखावा करता है। यह वर्तमान में gnu_get_libc_X()फ़ंक्शंस को लागू नहीं करता है , लेकिन यह लागू होता है getconfजो गलत भी हो सकता है (मुझे संदेह है कि इसके लिए एक खाली उत्तर देता है getconf GNU_LIBC_VERSION, मेरा बिल्ड एनवी आज व्यर्थ है इसलिए मैं पुष्टि नहीं कर सकता।)

असंभावित घटना में आप डाइटलिबक का उपयोग कर रहे हैं , रनिंग diet -vसंस्करण प्रदर्शित करेगा।

(Fwiw, autoconf का उपयोग कर सॉफ्टवेयर के साथ कई वर्षों से मैं अनियंत्रित-के लिए के साथ और अधिक समस्याओं लिया है gccऔर g++साथ की तुलना में आवश्यकताओं की जाँच के लिए glibc सुविधाओं।)


5

GNU लिबास (एक रूप या दूसरे में सबसे अधिक लिनक्स वितरण क्या उपयोग करता है) सख्त बैकवर्ड संगतता रखने के लिए महान लंबाई में जाता है। इसलिए आपको केवल तभी परेशानी में दौड़ना चाहिए जब आप किसी पुराने संस्करण (या "एंटरप्राइज़" वितरण पर बहुत अधिक नए बाइनरी को चलाने का प्रयास करते हैं, वे सामान्य रूप से संस्करणों को फ्रीज करते हैं, विशेष रूप से सी लाइब्रेरी की तरह नींव रखते हैं, कठोर द्विआधारी संगतता रखते हुए फ़िक्सपोर्टिंग करते हैं) । मेरा मानना ​​है कि आप अन्य पुस्तकालयों के साथ समस्याओं में चलने के लिए बहुत अधिक उत्तरदायी हैं (सी ++ में हाल की मेमोरी में कुछ एपीआई / एबीआई परिवर्तन थे, कुछ अन्य पुस्तकालय केवल पिछड़े संगतता के लिए परवाह नहीं करते हैं )।

अफसोस की बात है, यह सुनिश्चित करने का एकमात्र तरीका प्रयास करना है।


+1 वास्तव में उनके पास पिछड़ी संगतता के बारे में एक चार्ट है और मैं एकमात्र कारण मानूंगा कि यह सभी 100% नहीं है क्योंकि यह कोड के कारण है जो गूढ़ GNU एक्सटेंशन का शोषण करता है। हालाँकि, ऐसा कोई चार्ट नहीं है जिससे मैं आगे की अनुकूलता के बारे में जानता हूँ , जैसा कि आप ध्यान दें कि असली चिंता अधिक है।
सुनिलॉक्स

5

(यह अनिवार्य रूप से गोल्डीलॉक्स के उत्तर के समान है लेकिन हुड के नीचे क्या चल रहा है, इसके कुछ और स्पष्टीकरण के साथ।)

GNU libc के लिए कोर साझा लाइब्रेरी, libc.so.6(लिनक्स पर; हर्ड का एक अलग सोनम है), असामान्य संपत्ति (साझा पुस्तकालयों के लिए) है जिसे आप इसे एक निष्पादन योग्य के रूप में आमंत्रित कर सकते हैं। यदि आप करते हैं, तो यह उस तरह की चीज़ों को प्रिंट करता है जैसे कि GNU उपयोगिताओं को आमतौर पर प्रिंट करते हैं --version, इस तरह से:

$ /lib/x86_64-linux-gnu/libc.so.6 
GNU C Library (Debian EGLIBC 2.18-4) stable release version 2.18, by Roland McGrath et al.
Copyright (C) 2013 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.
Compiled by GNU CC version 4.8.2.
Compiled on a Linux 3.12.6 system on 2014-03-02.
Available extensions:
    crypt add-on version 2.1 by Michael Glad and others
    GNU Libidn by Simon Josefsson
    Native POSIX Threads Library by Ulrich Drepper et al
    BIND-8.2.3-T5B
libc ABIs: UNIQUE IFUNC
For bug reporting instructions, please see:
<http://www.debian.org/Bugs/>.

लेकिन निश्चित रूप से वह निर्देशिका जहां libc.so.6जीवन नहीं है $PATH, इसलिए आपको यह जानना होगा कि उसे कहां देखना है। यह में हो सकता है /lib, /lib64, /usr/lib, या (इस मामले में) के रूप में भी wackier कुछ। आसानी से, lddआपको बताएगा:

$ ldd /bin/sh | grep libc
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f5660b93000)

उस काम के लिए, निश्चित रूप से, आपको गतिशील रूप से जुड़े बाइनरी निष्पादन योग्य का पूरा पथनाम जानना होगा। shनिष्पादन में होने की गारंटी है /bin(क्योंकि बहुत से #!स्क्रिप्ट यह होने की उम्मीद है), और अपने आप में एक नहीं हो सकता #!स्क्रिप्ट। इसे वैधानिक रूप से जोड़ा जा सकता है, लेकिन मैंने ऐसी प्रणाली का सामना नहीं किया है जिसने कई वर्षों में ऐसा किया हो।

मुझे नहीं पता कि आप क्या करते हैं यदि आप uClibc या musl या कुछ अधिक विदेशी के साथ चल रहे हैं।


2
ठीक है, आपको पूरा रास्ता जानने की जरूरत नहीं है । आप हमेशा कर सकते हैं $ ldd $(which sh) | grep libc। : डी
मैट नॉर्डहॉफ़

5

इसे पाने का दूसरा तरीका:

getconf GNU_LIBC_VERSION

एक अच्छा, यह glibc-2.3.3 के बाद से मज़बूती से काम करना चाहिए
mr.spuratic
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.