2013-02-08 167 views
8

我想通過LD_PRELOAD替換原來的mmap()系統調用在預先識別的fd上,以便調用它的進程可以讀取先前創建的共享內存對象另一個過程與boost::interprocess。一切都很順利,除非我最終嘗試讀取mmap內存。在這種情況下,第一個進程會因分段錯誤而中止。原因是什麼?我不需要在共享內存對象上寫入權限。mmap()與LD_PRELOAD和boost :: interprocess不起作用

這是在預加載庫中的代碼:

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

你可以顯示你的'mmap'替換代碼嗎?它可能有問題。 – 2013-02-08 18:07:47

+0

我會盡快。 – Martin 2013-02-08 18:08:39

+0

是否確定要用自己的實現來替換流程中的每個單個mmap()調用?如果您使用的是LD_PRELOAD技巧,那麼會發生這種情況... – 2013-02-08 18:11:33

回答

7

你的問題是,你是有效的ret用一個本地引用,但以一種模糊的方式。您的mmap()覆蓋在堆棧中有一個interprocess::shared_memory_objectinterprocess::mapped_region,當您返回到客戶端時會被銷燬。在銷燬期間,提升包裝將取消映射內存區域,因此在客戶端代碼中訪問它不再有效。作爲一個簡單的修復,將這些變量設置爲靜態可以防止seg故障,儘管取決於應用程序的結構,但可能需要更復雜的解決方案。

相關問題