iOS: los commands de punto de interrupción multilínea LLDB no funcionan como se esperaba

Estoy tratando de hacer algo un poco elegante aquí, pero los documentos sugieren que debería ser posible. Tal vez LLDB todavía es demasiado nuevo, pero estoy recibiendo una gran cantidad de lockings / interlockings de debugging e incluso cuando eso no sucede, parece que no funciona como esperaba.

Estoy tratando de armar un contenedor de debugging alnetworkingedor de todas las llamadas de selector, para extraer el gráfico de llamadas de posts dentro de un cierto trozo de código. (Podría explicar por qué si realmente quiere saber, pero no es realmente relevante para el problema del depurador).

Empiezo con un punto de interrupción de Xcode en la línea donde quiero comenzar a rastrear cosas (para puntos de bonificación, esto sucede en un hilo secundario, pero antes de preguntar, no, nada en cualquier otro hilo está haciendo ningún acceso a este object o cualquier cosa en su propiedad subgráfico):

[myObject startProcessing]; 

El punto de interrupción se dispara y ejecuto "bt", solo para extraer:

 * thread #5: tid = 0x2203, 0x000277d2 ......... 

Luego hago algo levemente malvado: puse un punto de interrupción en objc_msgSend, justo en la instrucción donde llama al selector de objects reales. objc_msgSend se ve así:

 libobjc.A.dylib`objc_msgSend: ...(instructions)... 0x37babfa4: bx r12 ...(more instructions)... 

(En realidad, hay dos llamadas de bx, pero mantengamos las cosas simples.) Corro:

 breakpoint set -a 0x37babfa4 -t 0x2203 

(TID incluido porque estoy teniendo suficientes problemas para rastrear este hilo y no necesito interferencias irrelevantes).

Aquí es donde entra la secuencia de commands. La configuration descrita anteriormente funciona exactamente como me gustaría. Si reanudo la ejecución hasta que se dispare el punto de interrupción, puedo ejecutar:

 frame select 0 thread step-inst -m this-thread 5 frame info continue 

y el efecto será que el depurador:

  • se mueve al marco objc_msgSend
  • pasos por una instrucción, avanzando en el marco del selector de objects que apuntaba a
  • muestra detalles relevantes (tipo de object, llamado selector)
  • reanuda la ejecución

en ese momento puedo seguir pegando en esos cuatro commands una y otra vez y copyr el resultado hasta que me odio a mí mismo.

Si, por otro lado, ejecuto:

 breakpoint command add -s command 

y pegar en esos mismos commands exactos , todo se rompe. No avanza hacia el marco del selector de objects. No muestra los detalles del marco, o al less no los correctos, dependiendo de varios ajustes (vea a continuación), puede o no mostrar "objc_msgSend" como la function actual. No reanuda la ejecución.

En este caso, si pudiese lograr que ese ejemplo funcione, estaría mayormente feliz. Pero para incluso más puntos de bonificación, también he intentado esto con Python, lo que preferiría porque permitiría un logging mucho más sofisticado:

 breakpoint command add -s python > thread = frame.GetThread() > thread.StepInstruction(1) > newFrame = thread.GetFrameAtIndex(0) > print " " * thread.GetNumFrames() + newFrame.GetFunctionName() > process = thread.GetProcess() > process.Continue() > DONE 

De nuevo, no es bueno. De nuevo, dependiendo de los pequeños detalles, esto puede o no imprimir algo (generalmente objc_msgSend), pero nunca imprime lo correcto. Nunca da seguimiento a las instrucciones. Nunca reanuda la ejecución después.

Y de nuevo, la versión de Python funciona bien si lo hago a mano: si espero hasta que el punto de interrupción se dispare, entonces ejecute "script" e ingrese las mismas líneas exactas, funciona como se espera. Algunas partes incluso funcionarán de forma aislada, por ejemplo, si elimino todo, excepto las partes que obtienen el process y el process de llamada. Continuar () y activarlos automáticamente, eso "funciona" (lo que significa que veo que el indicador lldb parpadea rápidamente cuando suspende y reanuda ejecución. Por lo general lamento esto porque deja de responder y se cuelga poco después).

Entonces: ¿alguna idea? ¿La tecnología aún no está list, o me estoy perdiendo alguna pieza inteligente del rompecabezas que solucione todo? ¿O debería renunciar completamente y simplemente a vivir con el hecho de que hay algunas partes de objects internos que nunca entenderé? …

Los commands de punto de interrupción no pueden reanudar la ejecución y luego recuperar el control de nuevo, al less hoy. Hay muchas preguntas sin resolver sobre lo que sucedería si el punto de ruptura 1 está ejecutando el process y luego el punto de ruptura 2 es golpeado. Además de toda la cuestión de si la base de código realmente puede manejar correctamente los puntos de interrupción nesteds (fue diseñado para …), ¿qué significa si el punto de interrupción 2 decide que la ejecución debería detenerse? ¿Se desecha el estado del punto de ruptura 1?

Parece un poco esotérico preocuparse por un punto de ruptura que golpea otro punto de interrupción mientras camina por el process inferior, pero a less que se hayan elaborado todos los detalles, es fácil que el usuario se dispare en el pie. Por lo tanto, para hoy, los commands de punto de interrupción pueden detenerse cuando se golpea el punto de interrupción o continuar ejecutándose, pero no hay ninguna posibilidad de ejecutar un poco y hacer más procesamiento. Sé que esta sería una capacidad realmente útil para ciertas tareas, pero hay muchas cosas que deben pensarse antes de que se pueda hacer.

En algunos casos, es posible manejarlo al revés … si desea detenerse en el parser() funciones parser() solo cuando ha sido llamado por la function lexer() , es fácil colocar un punto de interrupción en lexer() con algunos commands de python para ir a una stack de ttwigs en la stack y ver cuál es la function de llamada. Si no es lexer() , continúe. No creo que esto se aplique a lo que intentas hacer, sin embargo.