21

何らかの理由で取得-EINVALしていますが、その理由は明らかではありません。ここでmmap、ファイルを開いて試行します。

if ((fd = open(argv[1], O_RDWR)) < 0)
{
    fprintf(stderr, "Failed to open %s: %s\n", argv[1], strerror(errno));
    return 1;
}

struct stat statbuf;
if (fstat(fd, &statbuf))
{
    fprintf(stderr, "stat filed: %s\n", strerror(errno));
    return 1;
}

char* fbase = mmap(NULL, statbuf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (fbase == MAP_FAILED)
{
    fprintf(stderr, "mmap failed: %s\n", strerror(errno));
    return 1;
}

編集: 追加する必要があります。エラーは で発生していmmapます。

4

2 に答える 2

58

MAP_SHAREDを to に変更するとMAP_PRIVATE、これが成功することがわかりました。

これが失敗した理由は微妙です。私のコードは VirtualBox VM 内で実行されており、しようとしていたファイルはmmapホスト マシンの共有ディレクトリにありました。VirtualBox 仮想ファイルシステムは、ハイパーバイザーの境界を越えるオプションを実装mmapしていないようです。MAP_SHARED

私の質問と彼の回答の両方に関する jxh の有益なコメントを読むと、このコードが彼のために機能していたことがわかりますmmap

MAP_SHAREDからへMAP_PRIVATEの切り替えもこれと一致するという私の観察: プライベートにマップされたメモリは他のプロセスから見えないため、仮想ファイルシステム ドライバーはおそらくメモリのマッピングに異議を唱えません。

解決策は、マップしたいファイルをゲストのハード ドライブに移動し、そこから操作を実行することでした。

于 2013-08-24T17:10:19.387 に答える
16

あなたstatbuf.st_size0です。長さパラメータがmmap()の場合、失敗します。0

EINVALエラーの理由として、次の 3 つが挙げられますmmap()

void *mmap(void *addr, size_t length, int prot, int flags,
           int fd, off_t offset);

...

  • addrlength、またはは好きではありませんoffset(例: 大きすぎる、またはページ境界に配置されていない)。
  • (Linux 2.6.12 以降)lengthは 0 でした。
  • flagsこれらの値のいずれも含まれていないMAP_PRIVATEか、両方が含まれていました。MAP_SHARED
于 2013-08-24T16:13:14.210 に答える