我试图通过mmap()
替换预先标识的fd上的原始LD_PRELOAD
系统调用,以便调用它的进程可以使用{{读取另一个进程先前创建的共享内存对象1}}。一切顺利,除非我最终尝试读取mmap的内存。在这种情况下,第一个进程以分段错误中止。原因是什么?我不需要对共享内存对象的写权限。
这是预加载库中的代码:
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());
答案 0 :(得分:7)
您的问题是您实际上是以一种稍微混淆的方式返回对本地的引用。您的mmap()覆盖在堆栈上有interprocess::shared_memory_object
和interprocess::mapped_region
,当您返回到客户端时会被销毁。在销毁期间,boost包装器将取消映射内存区域,因此在客户端代码中访问它不再有效。作为一个简单的修复,将这些变量设置为静态可以防止seg错误,但是根据应用程序的结构,可能需要更复杂的解决方案。