2

2 つの Linux マシンで動作が異なる単純な mmap プログラムがあります。

猫交流

   #include <sys/types.h>
   #include <sys/stat.h>
   #include <fcntl.h>
   #include <errno.h>


   #include <sys/mman.h>
   #include <err.h>
   #include <stdio.h>
   #include <stdlib.h>
   #include <string.h>
   #include <unistd.h>

   int
   main(void)
   {
           int fd = -1;
           char *A, *zero;

           if ((fd = open("./a.out", O_RDONLY, 0)) == -1)
                   exit(1);

           A = mmap(NULL, 65536, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, fd, 0);

           if (A == MAP_FAILED)
              printf("error %d, errno=%d\n", A, errno);
           else
               printf("OK %d\n", A);
           return (EXIT_SUCCESS);
   }

一方のマシンmmapでは成功しましたが、もう一方のマシンではエラーが出力されます (errno は 1)。

結果に関連する違いは次のstraceとおりです。

良いもの:

(2.6.9-78.ELsmp #1 SMP Wed Jul 9 15:46:26 EDT 2008 x86_64 x86_64 x86_64 GNU/Linux)
open("./a.out", O_RDONLY)               = 3
mmap(NULL, 65536, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0) = 0

失敗したもの:

( 2.6.18-194.26.1.el5 #1 SMP Fri Oct 29 14:21:16 EDT 2010 x86_64 x86_64 x86_64 GNU/Linux)
open("./a.out", O_RDONLY)               = 3
mmap(NULL, 65536, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0) = -1 EPERM (Operation not permitted)

失敗した場合、MAP_FIXED フラグを取り除くと、mmap は成功します。失敗したプロセスには、マッピングに使用できるメモリ空間 [0, 65535] がないようです。

この問題をどこで調べればよいかわかりません。異なる動作と失敗の原因は何ですか? または、より具体的には、障害が利用できない [0,65535] によるものであると推測した場合、あるマシンでは利用可能で、他のマシンでは利用できない原因は何でしょうか?

4

2 に答える 2

0

マニュアルページに従って mmap MAP_FIXED [Doesn't] interpret addr as a hint: place the mapping at exactly that address.。あなたの例では [address] ess は NULL です (最初の mmap 引数)。

NULL はほぼ常にゼロ ページにマップされるため、EPERM はおそらく予想される応答です。

その以前の動作ケースはおそらくバグです (A はファイルの内容を含むゼロ ページにマップされましたか?)

于 2019-01-31T00:00:59.893 に答える