2010-11-03 14 views
15

Hemos descubierto nuestra aplicación para el iPhone compleja (ObjC, C++, JavaScript/WebKit) tiene una fuga descriptores de archivo en circunstancias inusuales.en iOS/iPhone: "Demasiados archivos abiertos": necesita a la lista de archivos abiertos (como lsof)

Necesito saber qué archivos (por la ruta del archivo) que estamos dejando abierta.

Quiero algo así como el comando BSD "lsof", que, por supuesto, no está disponible en iOS 4, al menos no para mí. Idealmente una función C u ObjC. O una herramienta, como tiburón o instrumentos. Solo necesitamos los archivos para nuestra aplicación en ejecución, no (como con lsof) para todas las aplicaciones/procesos.

Hacemos todo tipo de cosas con los archivos, y el código que está fallando con "Demasiados archivos abiertos" no ha cambiado en años, y dado que las circunstancias son inusuales, esto podría haberse deslizado en meses atrás. Así que no hay necesidad de recordarme que mire el código que abre los archivos y asegúrese de cerrarlos. Ya lo se. Sería bueno estrecharlo con algo lsof-esque. Gracias.

Respuesta

26
#import <sys/types.h> 
#import <fcntl.h> 
#import <errno.h> 
#import <sys/param.h> 

+(void) lsof 
{ 
    int flags; 
    int fd; 
    char buf[MAXPATHLEN+1] ; 
    int n = 1 ; 

    for (fd = 0; fd < (int) FD_SETSIZE; fd++) { 
     errno = 0; 
     flags = fcntl(fd, F_GETFD, 0); 
     if (flags == -1 && errno) { 
      if (errno != EBADF) { 
       return ; 
      } 
      else 
       continue; 
     } 
     fcntl(fd , F_GETPATH, buf) ; 
     NSLog(@"File Descriptor %d number %d in use for: %s",fd,n , buf) ; 
     ++n ; 
    } 
} 
+1

Este fragmento finalizó tres días completos de depuración de un error unity3d. ¡Muchas gracias! – utahwithak

+0

¿Conoces el límite de archivos abiertos para iOS? Estoy obteniendo un problema similar con solo 32 archivos abiertos! –

+2

Lo siento por una pregunta estúpida, pero ¿dónde debería colocar este fragmento y cómo puedo usarlo para mi aplicación? – lub0v

2

¿Puede reproducir el problema de funcionamiento en el simulador?

Si es así, entonces en realidad se podría utilizar "lsof" ...


actualización:

Ok, si no se puede utilizar el simulador, entonces la idea # 2:

Cuando obtiene el error "demasiados archivos abiertos", llame a una función que itera a través de todos los descriptores de archivos abiertos y vuelca información sobre cada uno (por ejemplo, la longitud y los primeros bytes).

+0

Todavía tenemos que reproducir en el simulador. Y no podemos hacer que Instruments haga lo correcto contra el dispositivo. Gracias. –

0

que sugieren ejecuta su aplicación en un iPhone liberado, y el uso de antecedentes y MobileTerminal a echar un vistazo a los archivos actualmente abiertos.

Usted puede obtener un binario iPhone de lsof aquí: http://modmyi.com/cydia/package.php?id=6945

+0

Gracias.Tenemos un último dispositivo con jailbreak aquí. Pero esto y su jailbreaking son más antiguos y no toleraba la instalación de lsof. –

2

no puedes interceptar todo el archivo se abre con su propia función, por ejemplo my_fopen, y almacenar los descriptores junto con sus nombres de manera que cuando se tiene demasiado muchos archivos abiertos, puede ir a través de su lista para ver lo que está tomando todos los descriptores?

+0

+1 esta es una táctica excelente –

+0

Sí, utilicé esto en un juego de PSP ya que me encontraba con el mismo problema (el archivo filtrado maneja hasta que el sistema dice "lo siento amigo, no puedo abrir más archivos"). –

+0

¿Quiere decir llamar a my_fopen en lugar de fopen? Podríamos si usáramos fopen directamente para abrir todos los archivos, pero abrimos archivos de C++ (fstream), ObjC y probablemente (indirectamente) javascript/webkit. Y los enchufes también consumen FD. ¿Sugiere algún gancho de bajo nivel o algún truco de enlazador para reemplazar fopen? Gracias. –

1

Instruments.app podría ser capaz de ayudarle (/Developer/Applications/Instruments.app). Ejecute su aplicación utilizando la herramienta de Uso del sistema en Instruments, y probablemente le muestre lo que necesita saber. Lo mejor de todo es que se puede usar mientras se ejecuta la aplicación en su dispositivo, sin tener que jailbreaking.

+0

No podemos hacer que Instruments haga lo correcto contra el dispositivo en este caso. Gracias –

2

Si los instrumentos no funcionan bien para sus propósitos, mi siguiente recomendación sería ejecutar su aplicación en el simulador, y usar fs_usage en la línea de comandos para rastrear los descriptores de archivos que está abriendo y cerrando. Algo como esto:

  1. En la terminal, ejecutar "sudo fs_usage -f filesys MyAppName", en sustitución de MyAppName con el nombre de su aplicación.
  2. Inicie su aplicación.
  3. Observe los comandos de abrir y cerrar del descriptor de archivo emitidos por fs_usage para ver qué archivos está dejando abiertos.
Cuestiones relacionadas