2013-02-08 13 views
8

पर काम नहीं करता है। मैं सिस्टम कॉल को LD_PRELOAD के माध्यम से पूर्व-पहचाने गए एफडी पर प्रतिस्थापित करने की कोशिश कर रहा हूं, ताकि इसे कॉल करने की प्रक्रिया पहले से बनाई गई साझा मेमोरी ऑब्जेक्ट को पढ़ सके boost::interprocess के साथ एक और प्रक्रिया। सब कुछ ठीक हो जाता है, सिवाय इसके कि जब मैं आखिरकार mmaped स्मृति को पढ़ने की कोशिश करता हूं। उस स्थिति में पहली प्रक्रिया एक सेगमेंटेशन गलती के साथ बंद हो जाती है। कारण क्या हो सकता है? मुझे साझा मेमोरी ऑब्जेक्ट पर लेखन अनुमतियों की आवश्यकता नहीं है।mmap() एलडी_PRELOAD और boost :: इंटरप्रोसेस

void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset) { 
    static void* (*o_mmap) (void *, size_t, int, int, int, off_t) = 
     o_mmap = (void*(*)(void *, size_t, int, int, int, off_t)) dlsym(RTLD_NEXT, "mmap"); 
    if (!o_mmap) 
     std::cout << "mmap() preload failed\n"; 
    if (fd != my_fd) 
     return (*o_mmap)(start, length, prot, flags, fd, offset); 
    interprocess::shared_memory_object shm (interprocess::open_only, "obj", interprocess::read_only); 
    interprocess::mapped_region region(shm, interprocess::read_only, 0, length, start); 
    std::cout << "mmap() overridden. addr =" << region.get_address() << " length: " << region.get_size() << " start: " << start << "\n"; 
    return region.get_address(); 
} 

कार्यक्रम साझा स्मृति वस्तु बनाने के कोड है::

//Create a shared memory object. 
    shared_memory_object shm (create_only, "obj", read_write); 

    //Set size 
    shm.truncate(1000); 

    //Map the whole shared memory in this process 
    mapped_region region(shm, read_write); 

    //Write all the memory to 1 
    std::memset(region.get_address(), 1, region.get_size()); 

कार्यक्रम का कोड (जो segfaults)

यह प्री-लोडेड पुस्तकालय में कोड है ऊपर साझा की गई स्मृति को पढ़ने की कोशिश कर रहा है:

int fd = open(my_file, O_RDONLY); 

    void* addr = mmap(0, 1000, PROT_READ, MAP_SHARED, fd, 0); // Okay 

    //Check that memory was initialized to 1 
    char *mem = static_cast<char*>(addr); 
    for(std::size_t i = 0; i < 1000; ++i) 
    if(*mem++ != 1) // SEGFAULT! 
     return 1; //Error checking memory 
+0

क्या आप अपने 'एमएमएपी' प्रतिस्थापन का कोड दिखा सकते हैं? इसमें कुछ गड़बड़ हो सकती है। –

+0

मैं जितनी जल्दी हो सकेगा। – Martin

+0

क्या आप वाकई अपने प्रक्रिया में अपने एकल कार्यान्वयन के साथ प्रत्येक एकल mmap() कॉल को प्रतिस्थापित करना चाहते हैं? यदि आप एलडी_PRELOAD चाल का उपयोग कर रहे हैं, तो यह ठीक होगा ... –

उत्तर

7

आपकी समस्या यह है कि आप प्रभावी ढंग से पीछे हट रहे हैं एक स्थानीय के संदर्भ में, लेकिन थोड़ा अपमानजनक तरीके से। आपके एमएमएपी() ओवरराइड में स्टैक पर interprocess::shared_memory_object और interprocess::mapped_region है, जो क्लाइंट पर वापस आने पर नष्ट हो जाते हैं। विनाश के दौरान, बूस्ट रैपर मेमोरी एरिया को अनैप कर देंगे, इसलिए अब यह आपके क्लाइंट कोड में एक्सेस करने के लिए मान्य नहीं है। एक साधारण फिक्स के रूप में, इन चरों को स्थैतिक बनाना सीजी गलती को रोक देगा, हालांकि आपके आवेदन की संरचना के आधार पर एक और जटिल समाधान की आवश्यकता हो सकती है।

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