"/proc/../as"와 같이 Solaris에서 max(off64_t)보다 큰 파일

"/proc/../as"와 같이 Solaris에서 max(off64_t)보다 큰 파일

최대 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가 50비트이면 충분할 때 전체 64비트 주소 공간을 사용하는 것처럼 보이는 것은 부끄러운 일입니다. psinfo_t.pr_argv를 사용하는 Sun의 예는 SPARC 및 x86에서만 작동하지 않는 것 같습니다. 이 문제를 해결할 방법이 있나요?

답변1

Solaris x86-64에는 크기가 2 63 을 초과하는 매우 큰 파일이 있습니다 . 즉, off64_t여기에는 프로세스 주소 공간 proc( /proc/<pid>/as.

다음 파일을 처리합니다.

  1. 등을 사용하지 마십시오 fopen. fseek(제가 테스트한 Solaris 버전에서는) "불법적인" 오프셋으로 혼란을 야기하는 libc 스트림 루틴을 신뢰하지 마십시오.
  2. 사용 open64, read.
  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 소스 코드를 검사하여 이러한 변환을 수행할 수 있다는 것을 알고 있지만 AIX와 같은 psinfo및 가 있는 다른 플랫폼에서도 작동할 것이라고 가정해서는 안 됩니다.pr_argv

    그러나 매우 큰 오프셋을 전달하면 "그냥 작동합니다".

관련 정보