2013-02-08 8 views
8

システムコールをLD_PRELOADで事前に識別されたfdで置き換えようとしています。これを呼び出すプロセスが以前に作成した共有メモリオブジェクトを読み取ることができます。別のプロセスはboost::interprocessです。私が最後にmmap'edメモリを読み込もうとしたときを除いて、すべてうまくいく。その場合、最初のプロセスはセグメンテーション違反で中止されます。理由は何でしょうか?私は共有メモリオブジェクトに対する書き込み許可を必要としません。mmap()でLD_PRELOADと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()); 

(セグメンテーション違反)プログラムのコード上記の共有メモリを読み取ろうとすると、次のようになります。

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'のコードを表示できますか?それに何か問題があるかもしれません。 –

+0

私はできるだけ早くします。 – Martin

+0

あなたのプロセス内のすべての単一のmmap()呼び出しをあなた自身の実装に置き換えたいのですか?あなたがLD_PRELOADトリックを使用している場合、それはまさに起こるでしょう... –

答えて

7

あなたの問題は、ローカルへの参照を返すが、やや難解な方法で行う。 mmap()のオーバーライドには、スタックにinterprocess::shared_memory_objectinterprocess::mapped_regionがあり、クライアントに戻ると破棄されます。破壊の間、ブーストラッパーはメモリー領域をマップ解除するので、もはやクライアントコードでアクセスすることはできません。簡単な修正として、これらの変数を静的にすると、segフォールトが防止されますが、アプリケーションの構造によってはより複雑な解決策が必要になることがあります。

関連する問題