How do I read or seek from a file that's bigger than the maximum off64_t? The problem arises because the address space of a process is represented in the /proc/.../as
file, which is a huge sparse file for 64-bit processes. It's really very big: on a sample process on Solaris x86-64, argv's address is 0xFFFFFD7FFFxxxxxx, that is, the very top of the address space is used. Pointers are unsigned, but an off64_t is signed, so can't reach anything in the top half of the address space file.
This obviously depends on the layout of the address space. On 32-bit systems, this isn't a problem (a long
offset isn't big enough, but an off64_t
easily works), and on x86-64 on linux (for example), the top of the process is 0x7fffxxxxxxxx (48 bits), so again an off64_t can refer to anything in the process's address space.
So, it's a shame that Solaris on x86-64 seems to use the whole 64-bit address space, when 50 bits is more than enough. Sun's examples of using psinfo_t.pr_argv just don't seem to work except on SPARC and x86. Is there any way around this problem?
Best Answer
There are on Solaris x86-64 some very large files, whose size exceeds 263, that is, the maximum size representable in an
off64_t
. This includes the file representing a process's address space inproc
(/proc/<pid>/as
).To deal with these files:
fopen
,fseek
, etc. Don't trust the libc stream routines, which (on the versions of Solaris I tested) mangle badly the "illegal" offsets.open64
,read
.To seek:
That is, on Solaris, we know that we can do this cast because of inspection of the OpenSolaris sources, but we should avoid assuming it works on other platforms with
psinfo
andpr_argv
(eg AIX).But, pass in your very large offset, and it does all "just work".