Solaris 上大于 max(off64_t) 的文件,例如“/proc/../as”

Nic*_*son 6 process 64bit solaris proc x86

如何从大于最大 off64_t 的文件中读取或查找?出现问题是因为进程的地址空间在/proc/.../as文件中表示,对于 64 位进程来说,这是一个巨大的稀疏文件。它真的很大:在Solaris x86-64上的示例进程上,argv的地址是0xFFFFFD7FFFxxxxxx,即使用了地址空间的最顶部。指针是无符号的,但 off64_t 是有符号的,因此无法到达地址空间文件上半部分的任何内容。

这显然取决于地址空间的布局。在 32 位系统上,这不是问题(long偏移量不够大,但off64_t很容易工作),在 linux 上的 x86-64 上(例如),进程的顶部是 0x7fffxxxxxxxx(48 位) ,所以 off64_t 再次可以引用进程地址空间中的任何内容。

因此,令人遗憾的是,x86-64 上的 Solaris 似乎使用整个 64 位地址空间,而 50 位已绰绰有余。Sun 使用 psinfo_t.pr_argv 的示例似乎除了在 SPARC 和 x86 上不起作用。有没有办法解决这个问题?

Nic*_*son 0

Solaris x86-64 上有一些非常大的文件,其大小超过 2 63,即off64_t. proc这包括( )中表示进程地址空间的文件/proc/<pid>/as

处理这些文件:

  1. 不要使用fopenfseek等。不要相信 libc 流例程,它(在我测试的 Solaris 版本上)会严重破坏“非法”偏移量。
  2. 使用open64read
  3. 寻求:

    static off64_t lseeku64(int file, uint64_t offset /* eg from pr_argv */)
    {
    #ifndef __sun
      if (offset > 0x7FFFFFFFFFFFFFFFllu) return -1;
    #endif
      return lseek64(file, offset, SEEK_SET);
    }
    
    Run Code Online (Sandbox Code Playgroud)

    也就是说,在 Solaris 上,我们知道我们可以通过检查 OpenSolaris 源代码来进行此转换,但我们应该避免假设它可以在具有psinfo和的其他平台上工作pr_argv(例如 AIX)。

    但是,传递非常大的偏移量,它就会“正常工作”。