2016-06-09 12 views
6

का उपयोग करके लिनक्स साझा लाइब्रेरी को पहले से लोड किया गया है या नहीं, यह जांचने के लिए कि dlopen() का उपयोग करने के लिए मैं परिचित हूं या नहीं, यह जांचने के लिए कि कोई साझा लाइब्रेरी dlopen() पर पूर्व कॉल का उपयोग कर किसी प्रक्रिया में लोड की गई है या नहीं, वर्तमान, इसलिए जैसे:एलडी_PRELOAD

void* lib = dlopen(lib_name, RTLD_NOLOAD); 
if (lib != NULL) { 
    ... 
} 

मैं हाल ही में एक ही पैटर्न लागू करने के लिए निर्धारित करने के लिए साझा पुस्तकालयों में से एक मुट्ठी में से एक एक प्रक्रिया अंतरिक्ष LD_PRELOAD का उपयोग कर में लोड कर दिया है की कोशिश की है। हालांकि सभी मामलों में, ऊपर उल्लिखित कॉल dlopen()NULL देता है।

तो बुनियादी तौर पर, अगर मैं इस कमांड लाइन का उपयोग कर

LD_PRELOAD=libawesome.so ./mycoolprocess 

और फिर mycoolprocess.c में कोड में निम्न जांच चलाने की प्रक्रिया शुरू

void* has_awesome = dlopen("libawesome.so", RTLD_NOLOAD); 
if (has_awesome != NULL) { 
    printf("libawesome is available\n"); 
} 

dlopen() करने के लिए कॉल हमेशा NULL रिटर्न कोई फर्क नहीं पड़ता कि साझा पुस्तकालय को LD_PRELOAD का उपयोग करके लोड किया गया है या नहीं। एंड्रयू हेनले की टिप्पणी के आधार पर मैंने dlopen को पुनः लोड किए गए साझा ऑब्जेक्ट्स में से एक के पूर्ण पथ के साथ कॉल करने का भी प्रयास किया, लेकिन इस मामले में dlopen साझा ऑब्जेक्ट को प्रीलोड होने के बावजूद अभी भी शून्य लौटाता है।

तो मेरे सवाल दोहरा है:

  1. चाहिए एक पुस्तकालय है कि LD_PRELOAD का उपयोग कर लोड किया गया है के लिए ऊपर पैटर्न काम करता है?
  2. कोई प्रक्रिया निर्धारित करने का कोई और तरीका है कि कोई विशिष्ट साझा लाइब्रेरी प्रीलोड हो गई है या नहीं?
+0

'/ lib' या'/usr/lib' में, 'LD_LIBRARY_PATH' पर्यावरण चर में मौजूद निर्देशिका में, बाइनरी के 'DT_RPATH' या' DT_RUNPATH' का एक निर्देशिका में प्रीलोडेड साझा ऑब्जेक्ट है, या अन्य निर्देशिका 'ldconfig' के माध्यम से कॉन्फ़िगर किया गया? यदि नहीं, तो आपको शायद 'dlopen() 'के लिए एक पूर्ण या सापेक्ष पथ प्रदान करना होगा। –

+0

प्रोग्राम एलडी_PRELOAD env var के अस्तित्व की जांच कर सकता है? – jftuga

+0

@AndrewHenle, प्रीलोड किए गए साझा ऑब्जेक्ट्स आमतौर पर/usr/lib/x86_64-linux में रहते हैं। LD_PRELOAD केवल पूर्ण या सापेक्ष पथ के बिना लाइब्रेरी नाम निर्दिष्ट करता है। –

उत्तर

1

क्रमशः नहीं और हाँ।

dlopen() और एलडी_PRELOAD चाल, हालांकि वे साझा पुस्तकालयों से निपटते हैं, मूल रूप से विभिन्न तरीकों से काम करते हैं।

एलडी_PRELOAD पर्यावरण चर गतिशील लिंकर/लोडर (ld-linux.so) द्वारा संभाला जाता है, और निष्पादन योग्य बाइनरी में स्थानांतरण स्थान के रिज़ॉल्यूशन को प्रभावित करता है। संक्षेप में, आपके कोड में प्रत्येक बिंदु पर जहां एक गतिशील लाइब्रेरी में परिभाषित फ़ंक्शन पर कॉल किया जाता है, तो लिंकर (बिल्ड समय पर) मेमोरी एड्रेस के लिए प्लेसहोल्डर डालने के लिए कूद जाएगा। रनटाइम पर, उन प्लेसहोल्डर्स को स्मृति में लोड की गई साझा लाइब्रेरी के आधार पर वास्तविक पते से प्रतिस्थापित किया जाता है, जिन्हें स्वयं निष्पादन योग्य में नामित किया जाता है, लेकिन यदि LD_PRELOAD का उपयोग किया जाता है तो ओवरराइड किया जा सकता है।

तो एक बार निष्पादन योग्य स्मृति में लोड हो जाने के बाद और उन सभी प्लेसहोल्डर्स को वास्तविक पते से भर दिया गया है, कहां से आया था यह कहने का कोई आसान (या पोर्टेबल) तरीका नहीं है। हालांकि ...

आप चल रहे प्रक्रिया 'मेमोरी मैप की जांच कर सकते हैं। लिनक्स पर, इसका मतलब होगा/proc/<pid>/मानचित्र के माध्यम से पार्सिंग। फ़ाइल सामग्री काफी आत्म-स्पष्टीकरणपूर्ण है, इसलिए बस यादृच्छिक रूप से एक चुनें और एक नज़र डालें।

कोई विचार नहीं कि आप इसे अन्य सिस्टम पर कैसे करेंगे, लेकिन मेरा मानना ​​है कि अधिकांश आधुनिक यूनिक्स में किसी प्रकार का एक/proc फाइल सिस्टम है।

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