2012-10-10 14 views
54

sé que puedo escribir print someFloatVariable cuando me puse un punto de interrupción o po [self someIvarHoldingAnObject], pero no puedo hacer cosas útiles, como:¿Cómo llamar a métodos o ejecutar código en depurador LLDB?

[self setAlpha:1]; 

Entonces escupe:

error: '[self' is not a valid command.

Lo extraño es que yo puede llamar al po [self someIvarHoldingAnObject] e imprimirá su descripción.

Creo que he visto un video hace un año donde alguien demostró cómo ejecutar código a través de la consola en tiempo de ejecución, y si no me equivoco, este tipo también proporcionó argumentos y asignó objetos a los punteros. ¿Como hacer eso?

+0

Hay un ejemplo [en lldb-for-gdb-users.txt] (http://opensource.apple.com/source/lldb/lldb-69/docs/lldb-for-gdb-users.txt) para C: 'expr (int) printf (" ... ")'. ¿Puede ser que prefijas la invocación de tu método con 'expr (type)'? – osgx

Respuesta

85

La referencia canónica para los comandos LLDB v. GDB es http://lldb.llvm.org/lldb-gdb.html

Usted desea utilizar el comando expr que evalúa una expresión. Es uno de los comandos lldb que toma "entrada en bruto" además de argumentos, por lo que a menudo necesita un "-" para indicar dónde terminan los argumentos (a expr) y comienzan los comandos. p.ej.

(lldb) expr -- [self setAlpha:1] 

Hay un atajo, "p", lo que hace el - para usted (pero no permite ningún argumento), por ejemplo,

(lldb) p [self setAlpha:1] 

Si la función (s) que está llamando no son parte de su programa, a menudo tendrá que declarar explícitamente su tipo de retorno por lo LLDB sabe cómo llamarlos. p.ej.

(lldb) p printf("hi\n") 
error: 'printf' has unknown return type; cast the call to its declared return type 
error: 1 errors parsing expression 
(lldb) p (int)printf("hi\n") 
(int) $0 = 3 
hi 
(lldb) 

Hay una forma ordenada de solucionar el problema del argumento de coma flotante, por cierto. Usted crea un archivo de "prefijo de expresión" que se agrega a cada expresión que ingrese en lldb, con un prototipo de sus métodos de clase. Por ejemplo, tengo una clase MyClass que hereda de NSObject, tiene dos métodos de interés, "setArg:" y "getArg" que establecen y obtienen un flotante ivar. Este es un pequeño ejemplo tonto, pero muestra cómo usarlo. Aquí hay un archivo de prefijo que escribí para LLDB:

@interface NSObject 
@end 
@interface MyClass : NSObject 
- init; 
- setArg: (float)arg; 
- (float) getArg; 
@end 

extern "C" { 
    int strcmp (const char *, const char *); 
    int printf(const char * __restrict, ...); 
    void puts (const char *); 
} 

en mi archivo ~/.lldbinit agrego

settings set target.expr-prefix /Users/jason/lldb-prefix.h 

y ahora que puedo hacer

(lldb) p [var getArg] 
(float) $0 = 0.5 
(lldb) p [var setArg:0.7] 
(id) $1 = 0x0000000100104740 
(lldb) p [var getArg] 
(float) $2 = 0.7 

Se dará cuenta de que incluí un par de la biblioteca C estándar funciona aquí también. Después de hacer esto, no es necesario volver a lanzar los tipos de devolución de estos, p.

(lldb) p printf("HI\n") 
<no result> 
HI 
(lldb) p strcmp ("HI", "THERE") 
(int) $3 = -12 

(. Un arreglo para que "< ningún resultado >" cosa ha estado comprometida con las fuentes LLDB TOT ya)

+0

expr - [self setAlpha: 0.5f] o expr - [self setAlpha: 1] ambos hacen que la vista en cuestión desaparezca completamente de la pantalla. Parece que algo está sucediendo, pero definitivamente no es lo correcto. Solo puedo escribir estos comandos cuando establezco un punto de interrupción. ¿O hay una manera de hacer cosas como esta mientras el código aún se está ejecutando/sin pausar? –

+0

No, necesita detener el proceso cuando llama a este método. Si este selector toma un tipo de letra flotante, hay una falla que puede estar golpeando con lldb de Xcode 4.5 - si el argumento de función toma un tipo de letra flotante y no tiene información de depuración, lldb no le da ninguna forma de pase el valor como un flotador. Lo pasará como un doble incondicional, siguiendo las viejas reglas de promoción de argumento sin prototipo de lenguaje C. Si lldb tiene información de depuración para esta clase, debería poder hacer lo correcto. Muchas instancias de este problema en la programación de ObjC serán arregladas en una versión futura. –

+0

NB: Si estás abordando el problema que quise decir con float v. Double, el valor que estás transfiriendo a tu setAlpha no será el que esperas, será un número loco de aspecto aleatorio que puede estar muy cerca de 0, por ejemplo. –

2

Si necesita varias líneas, utilice expression:

expression 

do { 
    try thing.save() 
} catch { 
    print(error) 
} 

// code will execute now 

en blanco línea para terminar y ejecutar el código.

Cuestiones relacionadas