在LLDB中查看数组:在Xcode 4.1中相当于GDB的“@”运算符

我想查看一个指针指向的元素数组。 在GDB中,这可以通过使用运算符“@”将指定的内存视为给定长度的人造数组来完成

*pointer @ length 

其中length是我想要查看的元素的数量。

上述语法在Xcode 4.1提供的LLDB中不起作用。

有没有办法如何在LLDB完成上述内容?

实际上有一个简单的方法来做到这一点,通过投掷指针指向数组。

例如,如果你有一个int* ptr ,并且你想把它看作一个十个整数的数组,你可以这样做

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

因为它只依赖于标准的C特性,所以这个方法没有任何插件或者特殊的设置。 它同样适用于其他debugging器,如GDB或CDB,尽pipe它们也具有用于打印数组的特殊语法。

我发现的唯一方法是通过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) 

在lldb中定义一个命令“parray”:

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

现在你可以使用“parray variable length ”:

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

使用Xcode 4.5.1(现在可能帮不了你),你可以在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] 

这个例子假定'指针'是一个64浮点数组: float pointer[64];

从马丁R答案开始我改进如下:

  1. 如果指针不是一个简单的variables,例如:

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

    然后“par.a.at 5”失败。

    我通过用“GetValueForVariablePath”replace“FindVariable”来解决这个问题。

  2. 现在,如果数组中的元素是聚合的,例如:

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

    然后“parray a.at 5”打印:a.at-> x,a.at-> y,a.at [2],a.at [3],a.at [4],因为GetChildAtIndex()返回成员的总量。

    我通过解决循环内部的“a.at”+“[”+ str(i)+“]”来解决这个问题,而不是解决“a.at”,然后检索它的子节点。

  3. 添加了一个可选的“第一个”参数(用法:parray [FIRST] COUNT),当您拥有大量元素时,这非常有用。

  4. 使它在初始化时执行“命令脚本添加-f parray.parray parray”

这是我的修改版本:

 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') 

从Xcode 8.0中的lldb开始,有一个新的内置parray命令。 所以你可以说:

 (lldb) parray <COUNT> <EXPRESSION> 

EXPRESSION的结果所指向的内存打印为由EXPRESSION指向的types的COUNT元素的数组。

如果计数存储在当前帧中的可用variables中,那么请记住您可以:

 (lldb) parray `count_variable` pointer_to_malloced_array 

这是一个普通的lldb特性,在反引号中包含的lldb中的任何命令行参数都会被评估为一个返回一个整数的expression式,然后在命令执行之前将该整数replace为该参数。

它似乎还没有得到支持。

你可以使用内存读取function(内存读取/ X),如

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

从该指针打印浮动十次。 这应该是gdb的@相同的function。

我试图添加评论,但这不是一个完整的答案发布,所以我做了我自己的答案。 这解决了获得“无价值”的问题。 您需要获取当前帧,因为我相信lldb.frame是在模块导入时设置的,所以如果您从.lldbinit加载模块,则在断点处停止时不会有当前帧。 如果您在断点处停止时导入或重新加载脚本,则其他版本将起作用。 以下版本应该始终工作。

 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) + "]") 

那么在这一点上,你可以写自己的自定义C函数,并调用它:

 call (int)myprint(args)