2008-10-23 21 views
15

मेरे पास लिनक्स पर एक निष्पादन योग्य है जो libfoo.so.1 (यह SONAME) को अपनी निर्भरताओं में से एक के रूप में लोड करता है (किसी अन्य साझा लाइब्रेरी के माध्यम से)। यह एक और सिस्टम लाइब्रेरी से भी जुड़ा हुआ है, जो बदले में सिस्टम संस्करण, libfoo.so.2 से लिंक करता है। नतीजतन, दोनोंlibfoo.so.1 और libfoo.so.2 निष्पादन के दौरान लोड किए गए हैं, और संस्करण 1 के साथ लाइब्रेरी से फ़ंक्शंस को कॉल करने के लिए कोड को कॉल करने के लिए संस्करण 2 के साथ एक नई सिस्टम लाइब्रेरी से कॉलिंग (बाइनरी-असंगत) फ़ंक्शन समाप्त होता है, क्योंकि कुछ प्रतीक रहते हैं वही। परिणाम आमतौर पर स्टैक तोड़ने और बाद में segfault है।विभिन्न संस्करणों के साथ कई साझा पुस्तकालयों को लोड करना

अब, पुरानी संस्करण के विरुद्ध लिंक करने वाली लाइब्रेरी एक बंद-स्रोत तृतीय-पक्ष लाइब्रेरी है, और मैं नियंत्रित नहीं कर सकता कि libfoo का संस्करण किसके विरुद्ध संकलित करता है। मान लीजिए कि, एकमात्र अन्य विकल्प शेष सिस्टम लाइब्रेरीज़ का एक समूह पुनर्निर्माण कर रहा है जो वर्तमान में libfoo.so.2 से libfoo.so.1 से लिंक करने के लिए लिंक करता है।

क्या पुरानी libfoo से जुड़ी स्थानीय प्रतियों के साथ सिस्टम लाइब्रेरी को बदलने से बचने का कोई तरीका है? क्या मैं दोनों पुस्तकालयों को लोड कर सकता हूं और कोड को प्रतीक के सही संस्करण को कॉल कर सकता हूं? तो मुझे कुछ विशेष प्रतीक-स्तर संस्करण की आवश्यकता है?

+0

एलेक्स: आपने समस्या को कैसे हल किया? क्या आप इसे हमारे साथ साझा कर सकते हैं? – Nawaz

+0

@ नवाज मुझे बिल्कुल याद नहीं है, यह 9 साल पहले रहा है! मैं _think_ मैंने छोड़ दिया और इसे बनाया ताकि लाइब्रेरी का केवल एक संस्करण लोड हो। –

+0

एलेक्स, [इस लेख] (https://blog.habets.se/2012/05/Shared- पुस्तकालय-diamond-problem.html) इस समस्या के बारे में बात करते हैं और एक समाधान का भी सुझाव दिया है। मैंने अभी तक कोशिश नहीं की है। लेकिन यह जानना/अन्वेषण करना दिलचस्प है। – Nawaz

उत्तर

0

मैं केवल एक काम के आसपास आ सकता हूं। जो आप उपयोग कर रहे हैं "सिस्टम लाइब्रेरी" के एक संस्करण को स्थिर रूप से लिंक करना होगा। अपने स्थिर निर्माण के लिए, आप इसे पुराने संस्करण पुस्तकालय के समान पुराने संस्करण के खिलाफ लिंक कर सकते हैं। यह देखते हुए कि यह नए संस्करण पर भरोसा नहीं करता है ...

शायद तीसरे पक्ष की लाइब्रेरी को सामान्य तरीके से जोड़ने के साथ इन समस्याओं से बचना भी संभव है। इसके बजाए, आपका प्रोग्राम इसे निष्पादन समय पर लोड कर सकता है। शायद तब बाकी के खिलाफ छाया हो सकती है। लेकिन मुझे इसके बारे में बहुत कुछ पता नहीं है।

7

आप कुछ संस्करण स्क्रिप्ट चाल करने में सक्षम हो सकता है:

http://sunsite.ualberta.ca/Documentation/Gnu/binutils-2.9.1/html_node/ld_26.html

यह आवश्यकता हो सकती है कि आप अपने lib के चारों ओर एक आवरण है कि libfoo.so.1 कि कुछ प्रतीकों को स्पष्ट रूप से और मास्क निर्यात में खींचती बारे में अन्य सभी स्थानीय के रूप में। उदाहरण के लिए:

MYSYMS { वैश्विक: foo1; foo2; स्थानीय: *; };

और इस का उपयोग जब आप लिंक है कि आवरण की तरह:

जीसीसी कमरा साझा -Wl, - संस्करण स्क्रिप्ट, mysyms.map -ओ mylib wrapper.o -lfoo एल/path/to/foo। तो .1

यह libfoo.so.1 के प्रतीक को रैपर में स्थानीय बनाना चाहिए और मुख्य exe के लिए उपलब्ध नहीं होना चाहिए।

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

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