LINUX.ORG.RU

boost interprocess валится при удалении общей памяти из библиотеки

 , ,


0

1

Доброго всем времени суток. Использую boost::interprocess::shared_memory_object для выделения общей памяти при межпроцессном взаимодействии, но shared_memory_object живёт в библиотеке и при вызове boost::interprocess::shared_memory_object::remove программа падает, если этот же код выполнить просто в исполняемом файле, то всё пройдёт отлично. Подскажите что я делаю не так?

Нижеприведённый код будет работать в исполняемом файле, но упадёт при remove (последняя строка), если его вынести в библиотеку

    namespace bip = boost::interprocess;
    std::unique_ptr pMem = std::make_unique<bip::shared_memory_object>(bip::create_only, "Name", bip::read_write);
    pMem->truncate(4);
    std::unique_ptr pMemReg = std::make_unique<bip::mapped_region>(*pMem.get(), bip::read_write);

    char *ar=nullptr;
    ar = static_cast<char*>(pMemReg->get_address());
    std::memset(ar,0,4);
    ar[0]=1;
    ar[1]=2;

    bip::shared_memory_object::remove("Name");

Похоже проблема проявляется только под виндой, под линуксом всё работает



Последнее исправление: seijuurou (всего исправлений: 1)

std::unique_ptr pMemReg = std::make_unique<bip::mapped_region>(*pMem.get(), bip::read_write);

*pMem.get()

Ни разу не работал с boost::interprocess, но ты уверен, что здесь не напортачил с владением? Нет ли здесь двойного освобождения памяти? Попробуй для теста сделать без unique_ptr.

ox55ff ★★★★★
()

А как упадёт? Segmentation Fault или прилетает необработанное исключение?

В документации на это что-то есть: Removing shared memory

И можешь собрать минимальный проект, который воспроизведёт проблему?

Далее по тексту:

std::unique_ptr pMem = std::make_unique<bip::shared_memory_object>(bip::create_only, "Name", bip::read_write);
pMem->truncate(4);
    std::unique_ptr pMemReg = std::make_unique<bip::mapped_region>(*pMem.get(), bip::read_write);

Скорее всего у тебя pMem потом куда-то передаётся? Но всё же, почему не перемещать сам shared_memory_object, и этот код свести к:

bip::shared_memory_object mem(bip::create_only, "Name", bip::read_write);
mem.truncate(4);

bip::mapped_region memReg(mem, bip::read_write);

По выходу из области видимости объект разрушится, но уничтожения SHM блока не произойдёт.

В общем, я стараюсь в куче лишний раз объекты не создавать, если ситуация позволяет.

В любом случае, минимальный воспроизводимый пример, спрошенный в начале - первоочередное. Скидывай, погляжу.

hatred ★★★
()

Я бы сказал: strace в студию.

bugfixer ★★★★★
()
Ответ на: комментарий от ox55ff

Пробовал, вместо unique_ptr делал обычный указатель, создавал через new, проблема сохраняется

seijuurou
() автор топика
Ответ на: комментарий от kawaii_neko

Если написать вот так

int main(int argc, char **argv) {
    namespace bip = boost::interprocess;
    std::unique_ptr pMem = std::make_unique<bip::shared_memory_object>(bip::create_only, "Name", bip::read_write);
    pMem->truncate(4);
    std::unique_ptr pMemReg = std::make_unique<bip::mapped_region>(*pMem.get(), bip::read_write);

    char *ar=nullptr;
    ar = static_cast<char*>(pMemReg->get_address());
    std::memset(ar,0,4);
    ar[0]=1;
    ar[1]=2;

    bip::shared_memory_object::remove("Name");
    return 0;
}
то всё будет работать, но если засунуть это в деструктор класса в dll, на remove всё упадёт (хотя тоже самое для *.so в линуксе работает нормально)

seijuurou
() автор топика
Ответ на: комментарий от kawaii_neko

Конечно понимаю, но чем плох деструктор? pMemReg и pMem это поля класса, существующего в dll, пока мы не вышли из деструктора эти поля никто не уничтожил. Тогда почему мы в нём падаем? В любом другом месте этого класса вызови bip::shared_memory_object::remove(«Name») и всё будет хорошо

seijuurou
() автор топика
Ответ на: комментарий от seijuurou

Так ты архив проекта, который можно собрать и рукой потыкать и на котором проблема проявляется, дай?

hatred ★★★
()
Ответ на: комментарий от seijuurou

Понятия не имею, о каких полях ты говоришь. В приведенном тобой коде remove зовется, в то время, когда в нем еще живут какие-то объекты. В официальной документации в примере прямо-таки подчеркивают, что так делать не надо.

Связано ли это как-то с тем, что у тебя что-то там падает? Наверняка.

Имеет ли к этому отношение тот факт, что «в линуксе все работает»? Нет, потому что в Windows нету семантики POSIX shared memory и это эмулируется через mmapped-файлы.

Скажет ли тебе кто-нибудь на ресурсе, посвященном Linux/*nix, что же именно не так идет в win32 коде boost? Я бы особо не расчитывал.

kawaii_neko ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.