xcode debugging xcode4 llvm lldb

Ver matriz en LLDB: equivalente del operador ''@'' de GDB en Xcode 4.1



debugging xcode4 (8)

Bueno, en ese punto, también puedes escribir tu propia función C personalizada e invocarla con:

call (int)myprint(args)

Me gustaría ver una serie de elementos apuntados por un puntero. En GDB esto se puede hacer tratando la memoria puntiaguda como una matriz artificial de una longitud determinada utilizando el operador ''@'' como

*pointer @ length

donde la length es la cantidad de elementos que quiero ver.

La sintaxis anterior no funciona en LLDB suministrado con Xcode 4.1.

¿Hay alguna forma de cómo lograr lo anterior en LLDB?


Comenzando con la respuesta de Martin R, la mejoré de la siguiente manera:

  1. Si el puntero no es una variable simple, por ejemplo:

    struct { int* at; size_t size; } a;

    Entonces "parray a.at 5" falla.

    Lo arreglé reemplazando "FindVariable" con "GetValueForVariablePath".

  2. Ahora, ¿qué pasa si los elementos en su matriz son agregados, por ejemplo:

    struct { struct { float x; float y; }* at; size_t size; } a;

    Luego "parray a.at 5" imprime: a.at-> x, a.at-> y, a.at [2], a.at [3], a.at [4] porque GetChildAtIndex () devuelve miembros de agregados.

    Lo arreglé resolviendo "a.at" + "[" + str (i) + "]" dentro del bucle en lugar de resolver "a.at" y luego recuperar sus hijos.

  3. Se agregó un argumento "primero" opcional (Uso: parray [FIRST] COUNT), que es útil cuando tiene una gran cantidad de elementos.

  4. Hecho hacer el "comando script add -f parray.parray parray" en init

Aquí está mi versión modificada:

import lldb import shlex def parray(debugger, command, result, dict): args = shlex.split(command) if len(args) == 2: count = int(args[1]) indices = range(count) elif len(args) == 3: first = int(args[1]), count = int(args[2]) indices = range(first, first + count) else: print ''Usage: parray ARRAY [FIRST] COUNT'' return for i in indices: print lldb.frame.GetValueForVariablePath(args[0] + "[" + str(i) + "]") def __lldb_init_module(debugger, internal_dict): debugger.HandleCommand(''command script add -f parray.parray parray'')


Comenzando con lldb en Xcode 8.0, hay un nuevo comando de parray incorporado. Entonces puedes decir:

(lldb) parray <COUNT> <EXPRESSION>

para imprimir la memoria apuntada por el resultado de la EXPRESSION como una matriz de COUNT elementos del tipo al que apunta la expresión.

Si el recuento se almacena en una variable disponible en el marco actual, recuerde que puede hacer:

(lldb) parray `count_variable` pointer_to_malloced_array

Esa es una función de lldb general, cualquier argumento de línea de comandos en lldb rodeado de palos de retroceso se evalúa como una expresión que devuelve un número entero, y luego el entero se sustituye por el argumento antes de la ejecución del comando.


Con Xcode 4.5.1 (que puede o no ayudarle ahora), puede hacerlo en la consola lldb:

(lldb) type summary add -s "${var[0-63]}" "float *" (lldb) frame variable pointer (float *) pointer = 0x000000010ba92950 [0.0,1.0,2.0,3.0, ... ,63.0]

Este ejemplo asume que ''puntero'' es una matriz de 64 flotantes: float pointer[64];


En realidad, hay una manera simple de hacerlo, al convertir el puntero en un puntero a matriz.

Por ejemplo, si tiene un int* ptr , y desea verlo como una matriz de diez enteros, puede hacer

p *(int(*)[10])ptr

Debido a que solo se basa en las características C estándar, este método funciona sin complementos o configuraciones especiales. También funciona con otros depuradores como GDB o CDB, aunque también tienen sintaxis especializadas para imprimir matrices.


La única forma que encontré fue a través de un módulo de scripting de Python:

""" File: parray.py """ import lldb import shlex def parray(debugger, command, result, dict): args = shlex.split(command) va = lldb.frame.FindVariable(args[0]) for i in range(0, int(args[1])): print va.GetChildAtIndex(i, 0, 1)

Defina un comando "parray" en lldb:

(lldb) command script import /path/to/parray.py (lldb) command script add --function parray.parray parray

Ahora puedes usar " longitud variable de parray":

(lldb) parray a 5 (double) *a = 0 (double) [1] = 0 (double) [2] = 1.14468 (double) [3] = 2.28936 (double) [4] = 3.43404


No parece ser compatible todavía.

Puede usar la función de lectura de memoria (lectura de memoria / x), como

(lldb) memory read -ff -c10 `test`

para imprimir un flotador diez veces desde ese puntero. Esta debería ser la misma funcionalidad que gdb''s @.


Traté de agregar un comentario, pero eso no fue bueno para publicar una respuesta completa, así que hice mi propia respuesta. Esto resuelve el problema con obtener "Sin valor". Necesita obtener el marco actual, ya que creo que lldb.frame está configurado en el momento de importación del módulo, por lo que no tiene el marco actual cuando se detiene en un punto de interrupción si carga el módulo desde .lldbinit. La otra versión funcionaría si importas o vuelves a cargar la secuencia de comandos cuando te detuviste en el punto de interrupción. La siguiente versión siempre debería funcionar.

import lldb import shlex @lldb.command(''parray'', ''command script add -f parray.parray parray'') def parray(debugger, command, result, dict): target = debugger.GetSelectedTarget() process = target.GetProcess() thread = process.GetSelectedThread() frame = thread.GetSelectedFrame() args = shlex.split(command) if len(args) == 2: count = int(args[1]) indices = range(count) elif len(args) == 3: first = int(args[1]) count = int(args[2]) indices = range(first, first + count) else: print ''Usage: parray ARRAY [FIRST] COUNT'' return for i in indices: print frame.GetValueForVariablePath(args[0] + "[" + str(i) + "]")