¿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?

Author: Lukas, 2012-10-11

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" " ha sido confirmada al TOT lldb las fuentes ya están.)

 87
Author: Jason Molenda,
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.

 2
Author: João Souza,
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