2013-02-08 34 views
8

Tôi đang cố gắng thay thế cuộc gọi hệ thống ban đầu mmap() trên fd được xác định trước qua LD_PRELOAD, để quá trình gọi nó có thể đọc một đối tượng bộ nhớ dùng chung được tạo trước đó một quy trình khác với boost::interprocess. Mọi thứ diễn ra tốt đẹp, ngoại trừ khi cuối cùng tôi cố đọc bộ nhớ mmap'ed. Trong trường hợp đó, quá trình đầu tiên sẽ bị lỗi phân đoạn. Lý do có thể là gì? Tôi không cần quyền ghi trên đối tượng bộ nhớ dùng chung.mmap() với LD_PRELOAD và tăng :: interprocess không hoạt động

Đây là mã trong thư viện được nạp sẵn:

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(); 
} 

Mã của chương trình tạo ra các đối tượng bộ nhớ chia sẻ là:

//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()); 

Mã của chương trình (mà segfaults) cố gắng đọc bộ nhớ được chia sẻ ở trên là:

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

Bạn có thể hiển thị mã thay thế 'mmap' của mình không? Có thể có điều gì đó sai trái với nó. –

+0

Tôi sẽ càng sớm càng tốt. – Martin

+0

bạn có chắc chắn muốn thay thế mọi cuộc gọi mmap() trong quá trình của bạn bằng cách thực hiện của riêng bạn? Nếu bạn đang sử dụng thủ thuật LD_PRELOAD, đó là chính xác những gì sẽ xảy ra ... –

Trả lời

7

Vấn đề của bạn là bạn có hiệu quả urning một tham chiếu đến một địa phương, nhưng trong một cách hơi obfuscated. Ghi đè mmap() của bạn có một số interprocess::shared_memory_objectinterprocess::mapped_region trên ngăn xếp, bị hủy khi bạn quay lại ứng dụng khách. Trong quá trình hủy diệt, trình bao bọc tăng sẽ hủy bỏ vùng bộ nhớ, vì vậy nó không còn hợp lệ để truy cập nó trong mã máy khách của bạn nữa. Là một sửa chữa đơn giản, làm cho các biến tĩnh này sẽ ngăn chặn lỗi seg, mặc dù tùy thuộc vào cấu trúc của ứng dụng của bạn, một giải pháp phức tạp hơn có thể là cần thiết.