2013-02-08 25 views
8

LD_PRELOAD aracılığıyla önceden tanımlı bir fd'ye özgün mmap() sistem çağrısını değiştirmeye çalışıyorum, böylece daha önce oluşturulmuş bir paylaşılan bellek nesnesini okuyabilen işlem boost::interprocess ile başka bir işlem. Her şey iyi gidiyor, mmap'ed hafızasını okumayı denemem dışında. Bu durumda, ilk süreç bir segmentasyon hatasıyla iptal edilir. Sebebi ne olabilir? Paylaşılan bellek nesnesinde yazma izinlerine ihtiyacım yok.mmap() ile LD_PRELOAD ve boost :: arası süreç çalışmıyor

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(); 
} 

paylaşılan hafıza nesne oluşturma programı kodu:

//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()); 

programı kodu (çalışma sırasında parçalama arızası olan)

Bu

önceden yüklenmiş kütüphanede kodudur Yukarıdaki paylaşılan hafızayı okumaya çalışmak:

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' değiştirme kodunuzu gösterebilir misiniz? Bununla ilgili yanlış bir şey olabilir. –

+0

Mümkün olan en kısa zamanda olacağım. – Martin

+0

EVERY tek mmap() çağrısını kendi uygulamanızla değiştirmek istediğinizden emin misiniz? Eğer LD_PRELOAD numarasını kullanacaksanız, tam olarak ne olacağı tam olarak ... –

cevap

7

Sorununuz etkili bir şekilde ret Bir referansı yerel olarak değil, biraz sapkın bir şekilde zorlamak. Mmap() geçersiz kılma işleminiz, istemciye döndüğünüzde yok edilen interprocess::shared_memory_object ve interprocess::mapped_region numaralarına sahiptir. Yıkım sırasında, boost sarmalayıcılar bellek alanını unmap edecektir, bu yüzden artık müşteri kodunuza erişmek için geçerli değildir. Basit bir düzeltme olarak, bu değişkenlerin statik olmasını sağlamak, segment arızasını önler, ancak uygulamanızın yapısına bağlı olarak daha karmaşık bir çözüme ihtiyaç olabilir.