c++ - स्टेटिकली लिंकिंग ग्लिबेक को हतोत्साहित क्यों किया जाता है?




linker glibc (2)

अन्य उत्तरों में दिए गए कारण सही हैं, लेकिन वे सबसे महत्वपूर्ण कारण नहीं हैं।

सबसे महत्वपूर्ण कारण है कि ग्लिबक को सांख्यिकीय रूप से नहीं जोड़ा जाना चाहिए, यह है कि यह एनएसएस ( नाम सेवा स्विच ) मॉड्यूल और iconv रूपांतरणों को लोड करने के लिए, iconv व्यापक आंतरिक उपयोग करता है। मॉड्यूल स्वयं सी लाइब्रेरी फ़ंक्शंस को संदर्भित करते हैं। यदि मुख्य कार्यक्रम गतिशील रूप से सी लाइब्रेरी के साथ जुड़ा हुआ है, तो यह कोई समस्या नहीं है। लेकिन अगर मुख्य कार्यक्रम सी लाइब्रेरी के साथ सांख्यिकीय रूप से जुड़ा हुआ है, तो मॉड्यूल की लोड आवश्यकताओं को पूरा करने के लिए dlopen को C लाइब्रेरी की दूसरी कॉपी लोड करनी होगी।

इसका मतलब है कि आपके "स्टैटिकली लिंक्ड" प्रोग्राम को फाइल सिस्टम पर मौजूद libc.so.6 लिए अभी भी libc.so.6 की एक कॉपी की आवश्यकता है, साथ ही NSS या iconv या जो भी मॉड्यूल खुद हैं, साथ ही अन्य डायनेमिक लाइब्रेरी जो मॉड्यूल की आवश्यकता हो सकती हैं, जैसे ld-linux.so.2 , libresolv.so.2 , आदि। यह वह नहीं है जो लोग आमतौर पर चाहते हैं जब वे सांख्यिकीय रूप से लिंक करते हैं।

इसका अर्थ यह भी है कि स्टैटिकली लिंक्ड प्रोग्राम की सी लाइब्रेरी की दो प्रतियाँ अपने एड्रेस स्पेस में हैं, और वे लड़ सकते हैं जिनके stdout बफर का उपयोग किया जाना है, जो एक sbrk तर्क के साथ sbrk को कॉल sbrk , उस तरह की बात। इस काम को करने की कोशिश करने के लिए ग्लिबक के अंदर रक्षात्मक तर्क का एक गुच्छा है, लेकिन इसे काम करने की गारंटी कभी नहीं दी गई है।

आप सोच सकते हैं कि आपके कार्यक्रम को इस बारे में चिंता करने की आवश्यकता नहीं है क्योंकि यह कभी भी getaddrinfo या iconv कॉल नहीं करता है, लेकिन स्थानीय समर्थन iconv आंतरिक रूप से उपयोग करता है, जिसका अर्थ है कि कोई भी stdio.h फ़ंक्शन dlopen को कॉल ट्रिगर कर सकता है, और आप नहीं इसे नियंत्रित करते हैं, उपयोगकर्ता की पर्यावरण चर सेटिंग्स करते हैं।

अधिकांश स्रोत ऑनलाइन बताते हैं कि आप स्टेटिक रूप से ग्लिब लिंक कर सकते हैं, लेकिन ऐसा करने से हतोत्साहित करते हैं; जैसे सेंटो पैकेज रेपो :

The glibc-static package contains the C library static libraries
for -static linking.  You don't need these, unless you link statically,
which is highly discouraged.

ये स्रोत शायद ही कभी (या कभी नहीं) कहते हैं कि यह एक बुरा विचार क्यों होगा।


कार्यक्रम / glibc इंटरफ़ेस POSIX, C और C ++ मानकों और अन्य द्वारा मानकीकृत और प्रलेखित है। उदाहरण के लिए, fopen() फ़ंक्शन C मानक के अनुसार व्यवहार करता है, और pthread_mutex_lock() प्रतिOSOSIX।

glibc / कर्नेल इंटरफ़ेस मानकीकृत नहीं है। क्या fopen() तहत fopen() open() उपयोग करता है? या यह openat() उपयोग करता है? या कुछ और? अगले साल इसका क्या उपयोग होगा? तुम्हें पता नहीं है।

यदि glibc / कर्नेल इंटरफ़ेस बदलता है, तो एक प्रोग्राम जो कि परिवर्तित लेकिन स्टेटिक रूप से लिंक glibc का उपयोग करता है, किसी भी अधिक काम नहीं करेगा।

15+ साल पहले, सोलारिस ने इसी कारण से libc सभी स्थिर संस्करणों को हटा दिया।

स्टेटिक लिंकिंग - यह कहाँ गया?

सोलारिस 10 के साथ अब आप एक स्थिर निष्पादन योग्य नहीं बना सकते हैं। ऐसा नहीं है कि ld (1) स्थैतिक लिंकिंग, या अभिलेखागार का उपयोग करने की अनुमति नहीं देता है, यह केवल libc.a है, libc.so.1 का संग्रह संस्करण, अब प्रदान नहीं किया गया है। यह लाइब्रेरी उपयोगकर्ता भूमि और कर्नेल के बीच इंटरफेस प्रदान करती है, और इस लाइब्रेरी के बिना किसी भी प्रकार का एप्लिकेशन बनाना कठिन है।

हम पिछले कुछ समय से उपयोगकर्ताओं को स्टेटिक लिंकिंग के खिलाफ चेतावनी दे रहे हैं, और libc.a के खिलाफ लिंक करना विशेष रूप से समस्याग्रस्त रहा है। हर सोलारिस रिलीज़, या अपडेट (यहां तक ​​कि कुछ पैच) के परिणामस्वरूप कुछ एप्लिकेशन का परिणाम होता है जो कि libc.a के खिलाफ बनाया गया था, विफल। समस्या यह है कि libc को उपयोगकर्ता / कर्नेल सीमा से एक अनुप्रयोग को अलग करने के लिए माना जाता है, एक सीमा जो परिवर्तन से रिलीज़ होने तक गुजर सकती है।

यदि कोई एप्लिकेशन libc.a के विरुद्ध बनाया गया है, तो यह जिस भी कर्नेल इंटरफ़ेस को संदर्भित करता है, उसे संग्रह से निकाला जाता है और आवेदन का एक हिस्सा बन जाता है। इस प्रकार, यह एप्लिकेशन केवल एक कर्नेल पर चल सकता है जो उपयोग किए गए कर्नेल इंटरफेस के साथ इन-सिंक है। इन इंटरफेस को बदलना चाहिए, आवेदन अस्थिर जमीन पर फैल रहा है।

...

संपादित करें:

लिनक्स कर्नेल इंटरफ़ेस की स्थिरता का गंभीर overestimation प्रतीत होता है। विवरण के लिए लिनक्स कर्नेल एपीआई परिवर्तन / परिवर्धन देखें। संक्षेप में:







static-linking