2015-10-29 22 views
5

へのstrcpyを使用しているとき、私はこの起こって簡単なプログラムがあります。私のコードで間違ってバスエラー(コアダンプ)mmapによってファイル

int main(void) { 
    int fd; 
    const char *text = "This is a test"; 

    fd = open("/tmp/msyncTest", (O_CREAT | O_TRUNC | O_RDWR), (S_IRWXU | S_IRWXG | S_IRWXO)); 
    if (fd < 0) { 
      perror("open() error"); 
      return fd; 
    } 

    /* mmap the file. */ 
    void *address; 
    off_t my_offset = 0; 
    address = mmap(NULL, 4096, PROT_WRITE, MAP_SHARED, fd, my_offset); 

    if (address == MAP_FAILED) { 
      perror("mmap error. "); 
      return -1; 
    } 

    /* Move some data into the file using memory map. */ 
    strcpy((char *)address, text); 

    /* use msync to write changes to disk. */ 
    if (msync(address, 4096 , MS_SYNC) < 0) { 
    perror("msync failed with error:"); 
     return -1; 
    } 
    else { 
    printf("%s","msync completed successfully."); 
} 

    close(fd); 
    unlink("/tmp/msyncTest"); 
} 

何を?私はいくつかの簡単なテストを行いました。問題はstrcpyから来ているようです。しかし、定義によると、私は問題はないと思う。

+1

'fd'のチェック方法は表示されていません。 'len'と' my_offset'がどのように設定されているか。あなたが 'mmap()'呼び出しをチェックする方法。それらに関連付けられた何かがコードを失敗させたと推測できます。 –

+0

@JonathanLeffler [OK]を、私はすべてのコードを投稿します。 – HuangJie

+1

私たちはMCVE([最小限の完全かつ実証可能な例を作成するには?](http://stackoverflow.com/help/mcve))を見る必要があります。 –

答えて

4

fd = open("/tmp/msyncTest", (O_CREAT | O_TRUNC | O_RDWR), (S_IRWXU | S_IRWXG | S_IRWXO)); 

が成功した場合、fdは、ゼロ長ファイル(O_TRUNC)を参照します。 mmap()

address = mmap(NULL, 4096, PROT_WRITE, MAP_SHARED, fd, my_offset); 

への呼び出しは、メモリマッピングを確立しますが、ページがオブジェクトに対応していません。

http://pubs.opengroup.org/onlinepubs/7908799/xsh/mmap.htmlはこの状況について言いたいこと、次があります

システムを常にオブジェクトの末尾に任意の部分的なページがゼロで埋めます。さらに、システムは、オブジェクトの最後のページの、その終わりを超えた変更された部分を決して書き出すことはない。 paで始まり、オブジェクトの終わりに続く全ページからlenバイトまで続くアドレス範囲内の参照は、SIGBUS信号の配信をもたらす。同様に、Linux上man mmapがマップされた領域の

使用し、これらの信号をもたらすことができるノート


を[...]
SIGBUSはないバッファの部分へのアクセスを試みファイルに対応します(たとえば、ファイルの終わりを超えて、別のプロセスがファイルを切り捨てた場合も含めて)。

その結果、あなたは(あなたが匿名メモリをINGのmmap()ない限り)それをINGのmmap()前に、非ゼロ長にファイルをftruncate()必要があります。

+0

詳細: 'ftruncate'は' mmap'の前に起こる必要はありません。フォールトになるアクセスの前に行われる限り、 'mmap'の後に行うことができます。 –

+0

@R ..私は強く推奨しています:http://pubs.opengroup.org/onlinepubs/7908799/xsh/mmap.html 'マップされたファイルのサイズが、他のいくつかの結果としてmmap()の呼び出しの後に変化した場合、ファイルの追加または削除された部分に対応する、マップされた領域の部分への参照の影響は指定されていません。 'Linux' man mmap:マッピングの基礎となるファイルのサイズをファイルの追加または削除された領域に対応するページは指定されていません。 ' – EOF

+0

OK、お勧めします。どういうわけか私はいつもそれを逃した。 –

関連する問題