2010-09-07 15 views
28

मान लीजिए कि मैं खुली() सिस्टम कॉल को पूरी तरह से लेना चाहता हूं, शायद वास्तविक सिस्कल को लपेटने और कुछ लॉगिंग करने के लिए। One way to do this is to use LD_PRELOAD एक (उपयोगकर्ता द्वारा निर्मित) साझा ऑब्जेक्ट लाइब्रेरी लोड करने के लिए जो खुले() प्रविष्टि बिंदु को लेता है।मैं लिनक्स पर एक सिस्कल फ़ंक्शन को कैसे कार्यान्वित (या लपेट सकता हूं)?

उपयोगकर्ता द्वारा निर्मित खुले() दिनचर्या को ग्लिब फ़ंक्शन open() पर dlsym() द्वारा पॉइंटर प्राप्त होता है, और इसे कॉल किया जाता है।

ऊपर प्रस्तावित समाधान एक गतिशील समाधान है, हालांकि। मान लीजिए कि मैं अपने open() रैपर को स्थिर रूप से लिंक करना चाहता हूं। मैं यह कैसे करूंगा? मुझे लगता है कि तंत्र एक जैसा है, लेकिन मुझे लगता है कि उपयोगकर्ता द्वारा परिभाषित open() और libc open() के बीच एक प्रतीक संघर्ष होगा।

एक ही लक्ष्य प्राप्त करने के लिए कृपया कोई अन्य तकनीक साझा करें।

+0

आपके कोड में केवल एक रैपर फ़ंक्शन/मैक्रो चिपकाने के बारे में कैसे? –

+0

@ सेमस: मैं मैक्रोज़ का उपयोग नहीं करना पसंद करता हूं। मुझे वास्तव में कोई समस्या नहीं है। मैं सिर्फ एसओ ज्ञान बढ़ाने और कुछ नई चाल सीखने के लिए कह रहा हूं। –

उत्तर

56

आप ld द्वारा प्रदान की गई रैप सुविधा का उपयोग कर सकते हैं। man ld से:

--wrap symbol प्रतीक के लिए एक आवरण समारोह का उपयोग करें। symbol को कोई भी अनिर्धारित संदर्भ __wrap_symbol पर हल किया जाएगा।

__real_symbol के लिए कोई अपरिभाषित संदर्भ symbol पर हल किया जाएगा।

तो तुम सिर्फ अपने आवरण समारोह और __real_ के लिए उपसर्ग __wrap_ उपयोग करने के लिए जब आप वास्तविक फ़ंक्शन को कॉल करना चाहते हैं। एक साधारण उदाहरण है:

malloc_wrapper.c:

#include <stdio.h> 
void *__real_malloc (size_t); 

/* This function wraps the real malloc */ 
void * __wrap_malloc (size_t size) 
{ 
    void *lptr = __real_malloc(size); 
    printf("Malloc: %lu bytes @%p\n", size, lptr); 
    return lptr; 
} 

टेस्ट आवेदन testapp.c:

gcc -c malloc_wrapper.c 
gcc -c testapp.c 
gcc -Wl,-wrap,malloc testapp.o malloc_wrapper.o -o testapp 

जिसके परिणामस्वरूप आवेदन के उत्पादन में हो जाएगा:

#include <stdio.h> 
#include <stdlib.h> 
int main() 
{ 
    free(malloc(1024)); // malloc will resolve to __wrap_malloc 
    return 0; 
} 

फिर आवेदन संकलन:

$ ./testapp 
Malloc: 1024 bytes @0x20d8010 
+3

+1 यह बहुत अच्छा है: डी –

+1

ऐसा लगता है कि मॉलोक को कॉल करने वाला फ़ंक्शन गतिशील रूप से लिंक नहीं किया जा सकता है। उदाहरण के लिए, मैंने एक tools.c लिखा है, जिसमें फ़ंक्शन perform_alloc() है जो malloc को कॉल करता है। फिर अगर मैं libtols बना देता हूं। तो पहले और इसे गतिशील रूप से '-ltools'' से लिंक करें, '-Wl, -wrap, malloc' काम नहीं करेगा। – xanpeng

+1

जैसा कि http: // stackoverflow में उत्तर दिया गया है।कॉम/प्रश्न/3826108/है-किसी-एक-उदाहरण-के-रैपिंग-ए-फ़ंक्शन-इन-सी को सी ++ प्रोग्राम में इस कोड का उपयोग करते समय 'बाहरी "सी के साथ फ़ंक्शन परिभाषाओं को उपसर्ग करना आवश्यक है। – MKroehnert

2

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

gcc <BLAH> -nodefaultlibs <BLAH BLAH> -lYOUR_LIB <OTHER_LIBS> 

इस तरह अपने पुस्तकालयों खोज की है और पहली बार मिलती किया जाएगा निर्दिष्ट करने की आवश्यकता होगी।

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