¿Cómo llamar a métodos o ejecutar código en LLDB debugger?
Sé que puedo escribir print someFloatVariable
cuando establezco un punto de interrupción o po [self someIvarHoldingAnObject]
, pero no puedo hacer cosas útiles como:
[self setAlpha:1];
Entonces escupe:
Error: '[self' no es un comando válido.
Lo raro es que puedo llamar po [self someIvarHoldingAnObject]
y se 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 puntero. ¿Cómo hacer eso?
2 answers
La referencia canónica para los comandos gdb v. lldb es http://lldb.llvm.org/lldb-gdb.html
Desea utilizar el comando expr que evalúa una expresión. Es uno de los comandos lldb que toma "entrada sin procesar" además de los argumentos, por lo que a menudo necesita un " -- " para indicar dónde terminan los argumentos (a expr) y comienzan los comandos. por ejemplo,
(lldb) expr -- [self setAlpha:1]
Hay un atajo, "p", que hace el -- para usted (pero no permite ningún argumento), por ejemplo,
(lldb) p [self setAlpha:1]
Si las funciones que está llamando no son parte de su programa, a menudo necesitará declarar explícitamente su tipo de retorno para que lldb sepa cómo llamarlas. por ejemplo,
(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 manera ordenada de trabajar alrededor del problema del argumento de coma flotante, POR cierto. Crea un archivo de "prefijo de expresión" que se agrega a cada expresión que ingresa 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 se establece y obtener un flotador 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 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
Te darás cuenta de que he incluido un par de funciones estándar de la biblioteca C aquí también. Después de hacer esto, ya no necesito lanzar los tipos de retorno de estos, por ejemplo,
(lldb) p printf("HI\n")
<no result>
HI
(lldb) p strcmp ("HI", "THERE")
(int) $3 = -12
(una corrección para esa cosa"
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-22 10:15:48
Si necesita multilínea, use expression
:
expression
do {
try thing.save()
} catch {
print(error)
}
// code will execute now
Línea en blanco para finalizar y ejecutar el código.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-08 21:11:26