2012-03-27 12 views
6

Supongamos que tengo una aplicación para Mac o iOS basada en Cocoa. Me gustaría ejecutar un analizador estático de código fuente de mi de aplicacióno mi de aplicación binario para recuperar una lista de todos los métodos de Objective-C llamados en el mismo. ¿Hay alguna herramienta que pueda hacer esto?¿Cómo volcar estáticamente todos los métodos ObjC llamados en una aplicación Cocoa?

Unos pocos puntos:

  1. Busco a una solución estática. No estoy buscando un dynamic solution.

  2. Algo que se puede ejecutar contra un código binario o fuente es aceptable.

  3. Lo ideal sería que la salida no sería más que una enorme lista de engañados de métodos de Objective-C como:

     
    … 
    -[MyClass foo] 
    … 
    +[NSMutableString stringWithCapacity:] 
    … 
    -[NSString length] 
    … 
    
    (Si no es engañado de-eso está bien)

  4. Si otros tipos de símbolos (funciones C, vars estáticos, etc.) están presentes, eso está bien.

  5. estoy familiarizado con class-dump, pero que yo sepa, se vuelca el clases declaradas en sus binarios, no a los llamados métodos en su binario. Eso no es lo que estoy buscando. Si estoy equivocado, y usted puede hacer esto con el volcado de clase, por favor corríjanme.

  6. No estoy del todo seguro de que esto sea factible. Entonces, si no lo es, esa es una buena respuesta también. :)

Respuesta

9

Lo más cerca que yo sepa es otx, que es una envoltura alrededor de otool y puede reconstruir los selectores en objc_msgSend() sitios de llamadas.

http://otx.osxninja.com/

+0

Excelente puntero, gracias bbum! –

+1

El dominio ya no existe. http://web.archive.org/web/20130929164302/http://otx.osxninja.com/ del archivo punto org. – Klaas

0

Otra gran herramienta es class-dump que era siempre mi primera elección para el análisis estático.

+0

Lo siento, no leí tu pregunta correctamente ... – Chris

7

Si está buscando encontrar una lista COMPLETA de todos los métodos llamados, entonces esto es imposible, tanto estática como dinámicamente. La razón es que los métodos se pueden invocar de diversas maneras e incluso se pueden ensamblar de forma dinámica y programática.

Además de las invocaciones de métodos regulares que utilizan los mensajes de Objective-C como [Object message], también puede enviar mensajes utilizando las funciones C-API de objc/message.h, p. Ej. objc_msgSend(str, del). O puede enviarlos usando la API NSInvocation o con performSelector:withObject: (y métodos similares), consulte el examples here. Los selectores utilizados en todos estos casos pueden ser cadenas estáticas o incluso pueden construirse mediante programación a partir de cadenas, utilizando elementos como NSSelectorFromString.

Para empeorar las cosas, Objective-C incluso admite dynamic message resolution que permite que un objeto responda a mensajes que no se corresponden con ningún método.

Si está satisfecho con solo invocaciones de métodos específicos, al analizar el código fuente de los patrones enumerados anteriormente, obtendrá una lista mínima de los métodos que se pueden invocar durante la ejecución. Pero la lista puede ser incompleta (es decir, no contener métodos que pueden ser llamados) así como sobrecompletar (es decir, puede contener métodos que no se invocan en la práctica).

+0

Me gusta mucho esta respuesta. Plantea un punto de vital importancia: ninguna solución estática puede garantizar una cobertura del 100% debido a las características de tiempo de ejecución/lenguaje de ObjC que mencionó. No obstante, dejaré mi pregunta en pie, ya que creo que todavía habrá valor en una herramienta que podría encontrar el resto. –

+3

Creo que más grande que todas las rarezas de metaprogramación es el problema de no conocer los tipos de receptores en tiempo de compilación, lo cual es necesario para determinar qué método se llama. Cuando escribo '[foo length]', no se sabe si eso es '- [NSString length]', '- [FootballField length]' or '+ [SomePoorlyDesignedClass length]] - podría ser cualquier combinación de los tres en tiempo de ejecución, o incluso algún otro método cargado desde un complemento. Por lo tanto, puede determinar con bastante alta fidelidad qué * mensajes * se envían, pero es más difícil decir cómo se llaman * métodos * como resultado. – Chuck

+0

@Chuck Buen punto. No solo los selectores, sino también los objetos mismos pueden construirse dinámicamente. ¡+1 también para señalar la sutileza con respecto a los métodos de instancia y clase! – user8472

0
otool -oV /path to executable/ | grep name | awk '{print $3}' 
Cuestiones relacionadas