mmap () с LD_PRELOAD и boost :: interprocess не работает

Я пытаюсь заменить оригинал mmap() системный вызов по заранее определенному файлу через LD_PRELOAD, чтобы вызывающий его процесс мог читать объект общей памяти, созданный ранее другим процессом с 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();
}

Код программы, создающей объект общей памяти:

  //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

8

Решение

Ваша проблема в том, что вы эффективно возвращаете ссылку на местный, но слегка запутанный способ. Ваше переопределение mmap () имеет interprocess::shared_memory_object а также interprocess::mapped_region в стеке, которые уничтожаются при возврате к клиенту. Во время уничтожения бустеры обертки удаляют область памяти, поэтому доступ к ней в вашем клиентском коде больше недействителен. В качестве простого исправления статические переменные предотвратят ошибку seg, хотя в зависимости от структуры вашего приложения может потребоваться более сложное решение.

7

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]