2011-10-18 15 views
5

मैं एलडी_PRELOAD के माध्यम से कुछ इंटरपोजर्स के साथ मॉलोक/फ्री/कॉलोक/रीयलोक इत्यादि का संचालन करने की कोशिश कर रहा हूं। मेरे छोटे परीक्षण में, केवल malloc पर विचार किया जा रहा है, भले ही free पता चला है (आउटपुट देखें)।एलडी_PRELOAD केवल मॉलोक के लिए काम कर रहा है, मुफ्त

मुझे उम्मीद है कि आउटपुट में "नैनो: फ्री (एक्स)" रेखा होगी - लेकिन यह लाइन गुम है।

को देखते हुए

// compile with: gcc test.cc 
#include <stdio.h> 
#include <stdlib.h> 

int main(int argc, char* argv[]) { 

    void* p = malloc(123); 
    printf("HOST p=%p\n", p); 
    free(p); 
} 

और

// compile with: g++ -O2 -Wall -fPIC -ldl -o libnano.so -shared main.cc 
#include <stdio.h> 
#include <dlfcn.h> 

typedef void *(*MallocFunc)(size_t size); 
typedef void (*FreeFunc)(void*); 

// Original functions 
static MallocFunc real_malloc = NULL; 
static FreeFunc real_free = NULL; 

static void __nano_init(void) { 
    // Override original functions 
    real_malloc = (MallocFunc)dlsym(RTLD_NEXT, "malloc"); 
    if (NULL == real_malloc) { 
     fprintf(stderr, "Error in `dlsym`: %s\n", dlerror()); 
    } else { 
     fprintf(stderr, "NANO: malloc() replaced @%p\n", real_malloc); 
    } 

    real_free = (FreeFunc)dlsym(RTLD_NEXT, "free"); 
    if (NULL == real_free) { 
     fprintf(stderr, "Error in `dlsym`: %s\n", dlerror()); 
    } else { 
     fprintf(stderr, "NANO: free() replaced @%p\n", real_free); 
    } 
} 

// replacement functions 
void *malloc(size_t size) { 
    if(real_malloc==NULL) __nano_init(); 

    void *p = NULL; 
    fprintf(stderr, "NANO: malloc(%lu) = ", size); 
    p = real_malloc(size); 
    fprintf(stderr, "%p\n", p); 

    return p; 
} 

void free(void* ptr) { 
    if(real_free==NULL) __nano_init(); 

    fprintf(stderr, "NANO: free(%p)\n", ptr); 
    real_free(ptr); 

    return; 
} 

वास्तविक उत्पादन होता है:

% ./a.out 
NANO: malloc() replaced @0x3b36274dc0 
NANO: free() replaced @0x3b36272870 
NANO: malloc(123) = 0x601010 
HOST p=0x601010 

उत्तर

9

आप एक सी ++ संकलन कर रहे हैं; इसका मतलब यह है कि (डिफ़ॉल्ट रूप से) फ़ंक्शंस C++ ABI फिट करने के लिए नाम-उलझन में हैं। दुर्भाग्यवश, जिन कार्यों को आप हुक करने की कोशिश कर रहे हैं वे नाम-उलझन में हैं, इसलिए आप गलत (nonexistent) फ़ंक्शन को जोड़ना समाप्त कर देते हैं।

फिक्स या तो है) अपने रैपर को extern "C" { } ब्लॉक में परिभाषित करें या ए) सुनिश्चित करें कि आप फ़ंक्शन के लिए हेडर शामिल करें - जैसे #include <cstdlib>। यह malloc और free के लिए extern "C" रैपर के साथ घोषणाओं में खींच जाएगा, संकलक को नाम-मैंगल नहीं बताएगा।

कारण malloc काम करता है mallocलेकिन नहींfree के लिए एक घोषणा में शायद इसलिए है क्योंकि <stdio.h> या <dlfcn.h> खींचती है। इस प्रकार, malloc असंबद्ध है, लेकिन free उलझन में है।

यह भी ध्यान दें: यदि आप ग्लिब का उपयोग कर रहे हैं, तो आपको स्मृति आवंटन कार्यों को हुक करने के लिए malloc hooks का उपयोग करना चाहिए। glibc प्रतीक संस्करण के साथ कुछ सुंदर अजीब सामान करता है जो अन्यथा आपके हुक में हस्तक्षेप कर सकता है। इसका उपयोग करने का एक उदाहरण दस्तावेज से जुड़ा हुआ है - यदि आप C++ का उपयोग कर रहे हैं, तो extern "C" एस को न भूलें!

+0

अरग नाम मैंगलिंग। सटीक। यह आंकड़े बताता है कि मैं उन सभी उदाहरणों का उपयोग कर रहा था जहां सी/जीसीसी। मुझे पता होना चाहिए था कि जब मैं g ++ पर गया था। टिप के लिए धन्यवाद - अभी के लिए मैं सीधे LD_PRELOAD तकनीक का मूल्यांकन करना पसंद करूंगा। मैं malloc हुक के किसी भी फायदे के बारे में अनिश्चित हूँ। – Justicle

+0

@bdonian यदि आप खेल हैं तो मेरे यहां एक फॉलो अप प्रश्न है: http://stackoverflow.com/questions/7910666/problems-with-ld-preload-and-calloc-interposition-for-certain-executables – Justicle

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