在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答案开始我改进如下:
-
如果指针不是一个简单的variables,例如:
struct { int* at; size_t size; } a;
然后“par.a.at 5”失败。
我通过用“GetValueForVariablePath”replace“FindVariable”来解决这个问题。
-
现在,如果数组中的元素是聚合的,例如:
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”,然后检索它的子节点。
-
添加了一个可选的“第一个”参数(用法:parray [FIRST] COUNT),当您拥有大量元素时,这非常有用。
-
使它在初始化时执行“命令脚本添加-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)