C++ 带有LD_PRELOAD和boost::interprocess的mmap()不起作用

C++ 带有LD_PRELOAD和boost::interprocess的mmap()不起作用,c++,c,boost,glibc,libc,C++,C,Boost,Glibc,Libc,我试图通过LD\u PRELOAD替换预先识别的fd上的原始mmap()系统调用,以便调用它的进程可以读取以前由另一个进程使用boost::interprocess创建的共享内存对象。一切都进行得很顺利,除了我最后试着去读mmap的记忆。在这种情况下,第一个进程由于分段错误而中止。原因可能是什么?我不需要对共享内存对象的写入权限 这是预加载库中的代码: void *mmap(void *start, size_t length, int prot, int flags, int fd, off_

我试图通过
LD\u PRELOAD
替换预先识别的fd上的原始
mmap()
系统调用,以便调用它的进程可以读取以前由另一个进程使用
boost::interprocess
创建的共享内存对象。一切都进行得很顺利,除了我最后试着去读mmap的记忆。在这种情况下,第一个进程由于分段错误而中止。原因可能是什么?我不需要对共享内存对象的写入权限

这是预加载库中的代码:

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();
}
试图读取上述共享内存的程序(SEGFULTS)的代码为:

  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
int fd=open(仅我的文件);
void*addr=mmap(0,1000,保护读取,映射共享,fd,0);//可以
//检查内存是否已初始化为1
char*mem=静态_cast(addr);
对于(标准::尺寸i=0;i<1000;++i)
如果(*mem++!=1)//SEGFAULT!
返回1//错误检查内存

您的问题是,您实际上是在以一种稍微模糊的方式返回对本地的引用。mmap()覆盖在堆栈上有一个
interprocess::shared_memory_对象
interprocess::mapped_region
,当您返回到客户端时,这些对象将被销毁。在销毁过程中,boost包装器将取消映射内存区域,因此在客户端代码中访问它不再有效。作为一个简单的解决方案,将这些变量设置为静态可以防止seg故障,但根据应用程序的结构,可能需要更复杂的解决方案。

您能否显示
mmap
替换的代码?可能有问题。我会尽快解决。是否确实要用自己的实现替换流程中的每个mmap()调用?如果您使用的是LD_预加载技巧,那么这正是将要发生的事情……替换实际上只在预先确定的fd上定义良好的条件下发生。在所有其他情况下,调用原始mmap。实际上,拦截本身是好的,我可以得到共享对象,它的大小,我还可以得到区域开始地址并在mmap()中返回它。但是,一旦我在mmap()之后读取内存,就会出现seg故障。您的
mmap()
替换是否可重入?它所做的某些事情(包括打印调试输出!)本身可能会触发一个分配,该分配通过匿名
mmap()
提供服务。
  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