8

mmap()を介して事前に識別された fdの元のシステム コールを置き換えようとしています。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());

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

  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
4

1 に答える 1

7

あなたの問題は、ローカルへの参照を効果的に返しているが、少し難読化されていることです。mmap() オーバーライドのスタックにはinterprocess::shared_memory_objectandinterprocess::mapped_regionがあり、クライアントに戻ると破棄されます。破棄中、ブースト ラッパーはメモリ領域のマップを解除するため、クライアント コードでメモリ領域にアクセスすることはできなくなります。アプリケーションの構造によっては、より複雑な解決策が必要になる場合がありますが、簡単な修正として、これらの変数を静的にすることでセグ フォールトを防ぐことができます。

于 2013-02-12T15:41:32.543 に答える