2013-10-03 9 views
6

में लोड की गई मेरी साझा लाइब्रेरी के दो एबीआई-असंगत संस्करण का पता लगाएं मैंने कई असंगत संस्करणों के साथ एक साझा लाइब्रेरी लिखी है। मैं SONAME बदल गया है, तो वे कहा जाता है:एकल प्रोग्राम

  • lib_mylib.so.1.0.0 (पुराने पुस्तकालय)
  • lib_mylib.so.2.0.0

वहाँ केवल mylib में कुछ कार्य हैं। तो .1, अन्य केवल mylib.so.2 में हैं और कई फ़ंक्शन आम हैं (लेकिन कई ने तर्कों की गिनती बदल दी है)

और मुझे डर है कि Mylib के दोनों संस्करणों को एकल एप्लिकेशन में लिंक करना संभव है, उदाहरण के लिए जब आवेदन स्वयं बड़ा होता है और इसमें कई पुस्तकालय होते हैं। जब आवेदन आंशिक रूप से पुनर्निर्माण किया गया है, वहाँ ऐसी स्थिति हो सकता है: (mylib.so.1 साथ बनाया गया था - मेरे lib का पहला संस्करण)

  • आवेदन
  • app_lib1.so
  • app_lib2.so (बनाया गया था mylib.so.2 के साथ - दूसरा संस्करण)

मैंने पहले से ही इसमें दोनों संस्करणों के साथ आवेदन देखा है (ldd दोनों रिपोर्ट)।

तो, क्या यह पता लगाने के लिए mylib.so.2 पर कुछ जांच कोड जोड़ना संभव है कि लाइब्रेरी के दोनों संस्करण पहले ही लोड हो चुके हैं और उनके पास एबीआई/इंटरफेस विरोधाभासी है। (मैं lib_mylib.so.1 को इसमें कुछ जोड़ने के लिए संशोधित नहीं कर सकता)

उत्तर

1

वर्तमान में लोड की गई वस्तुओं की सूची प्राप्त करने के लिए आप /proc/self/maps को पार्स कर सकते हैं।

+0

मैं केवल अपनी लाइब्रेरी के निर्माता में '/ proc/self/maps' को पार्स कर सकता हूं। मुझे लगता है कि यह संभव है कि दूसरी लाइब्रेरी से मेरे कन्स्ट्रक्टर को चलाने के समय, पहली लाइब्रेरी को अभी तक स्मृति में लोड नहीं किया जाएगा (केस 1: mylib2 libs की सूची में mylib1 से पहले है; केस 2: mylib1 को dlopen का उपयोग करके लोड किया जाएगा कुछ समय बाद) – osgx

3

जब आप पाए गए तो इनिट और क्रैश के दौरान कुछ संस्करण -1-विशिष्ट प्रतीक (dlsym(3)) को हल करने के लिए आप अपनी संस्करण 2 लाइब्रेरी को संशोधित कर सकते हैं।

उदाहरण:

extern __attribute__((constructor)) void _version_check2() 
{ 
    if (dlsym(RTLD_DEFAULT, "version_1_function")) 
     abort(); 
} 

एक और अधिक सुंदर समाधान संस्करण 2 पुस्तकालय संस्करण 1 के व्यवहार की नकल करने देने के लिए है, लेकिन उस विरासत कोड परिचय देता है।

संपादित

भविष्य सबूत होने के लिए, आप भी एक स्थिर संस्करण वेरिएबल लागू कर सकते हैं और अगर यह मौजूदा मेल खाता है सभी फ़ंक्शन कॉल की जाँच करेगा। फिर भविष्य के संस्करणों में आपको उस चर के मूल्य को बदलने की आवश्यकता है और अगर मेल नहीं खाती है तो क्रैश।

संपादित 2

आप भी इस समारोह पर हर संस्करण 2 समारोह ताकि अभी या बाद में जब संस्करण 1 यदि आपका ऐप्स क्रैश लोड हो जाता है कॉल कर सकते हैं।

+0

या शायद लिनक्स-विशिष्ट 'dlopen (RTLD_NOLOAD, "lib_mylib.so.1.0.0") '। – rodrigo