Arquivos maiores que max (off64_t) no Solaris, por exemplo, “/proc/../as”

6

Como leio ou procuro de um arquivo maior que o máximo off64_t? O problema surge porque o espaço de endereço de um processo é representado no arquivo /proc/.../as , que é um arquivo esparso enorme para processos de 64 bits. É realmente muito grande: em um processo de amostra no Solaris x86-64, o endereço do argv é 0xFFFFFD7FFFxxxxxx, ou seja, o topo do espaço de endereço é usado. Os ponteiros não são assinados, mas um off64_t é assinado, portanto, não pode acessar nada na metade superior do arquivo de espaço de endereço.

Isso obviamente depende do layout do espaço de endereço. Em sistemas de 32 bits, isso não é um problema (um long offset não é grande o suficiente, mas um off64_t funciona facilmente) e no x86-64 no linux (por exemplo), o topo do processo é 0x7fffxxxxxxxx (48 bits), então, novamente, um off64_t pode se referir a qualquer coisa no espaço de endereço do processo.

Então, é uma pena que o Solaris no x86-64 pareça usar todo o espaço de endereço de 64 bits, quando 50 bits é mais que suficiente. Os exemplos de uso de psinfo_t.pr_argv da Sun simplesmente não parecem funcionar, exceto em SPARC e x86. Existe alguma maneira de contornar este problema?

    
por Nicholas Wilson 29.10.2012 / 12:36

1 resposta

0

Existem no Solaris x86-64 alguns arquivos muito grandes, cujo tamanho excede 2 63 , ou seja, o tamanho máximo representável em um off64_t . Isso inclui o arquivo que representa o espaço de endereço de um processo em proc ( /proc/<pid>/as ).

Para lidar com esses arquivos:

  1. Não use fopen , fseek , etc. Não confie nas rotinas de fluxo libc, que (nas versões do Solaris que testei) manipulam mal os deslocamentos "ilegais".
  2. Use open64 , read .
  3. Para procurar:

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

    Ou seja, no Solaris, sabemos que podemos fazer esse lançamento por causa da inspeção das fontes do OpenSolaris, mas devemos evitar que ele funcione em outras plataformas com psinfo e pr_argv (por exemplo, AIX).

    Mas, passe no seu offset muito grande e ele faz tudo "apenas funcione".

por 21.01.2013 / 12:34