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

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

如何读取或查找大于最大 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 上不起作用。有什么办法可以解决这个问题吗?

答案1

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);
    }
    

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

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

相关内容