我想查看由指针指向的元素数组。在GDB中,可以使用运算符“@”将指向的内存视为给定长度的人工数组来实现此目的。
*pointer @ length
length
是我想要查看的元素数量。
上述语法在Xcode 4.1提供的LLDB中不起作用。
是否有任何方法可以在LLDB中实现上述功能?
我想查看由指针指向的元素数组。在GDB中,可以使用运算符“@”将指向的内存视为给定长度的人工数组来实现此目的。
*pointer @ length
length
是我想要查看的元素数量。
上述语法在Xcode 4.1提供的LLDB中不起作用。
是否有任何方法可以在LLDB中实现上述功能?
在lldb中,有两种方法可以做到这一点。
最常见的是使用parray
lldb命令,它接受COUNT
和EXPRESSION
;EXPRESSION
将被求值并应该得出一个指向内存的指针。然后lldb将在该地址打印COUNT
个相同类型的元素。例如:
parray 10 ptr
其中,ptr
的类型为 int *
。
另外一种方法是通过将指针强制转换为指向数组的指针来完成。
例如,如果你有一个 int* ptr
,想将其视为包含十个整数的数组,可以这样做:
p *(int(*)[10])ptr
由于它仅依赖于标准的C功能,因此这种方法可以在没有任何插件或特殊设置的情况下工作。即使像GDB或CDB这样的其他调试器也有专门用于打印数组的语法,但它同样适用。
*(double(*)[10])value_type
。这将打印出所指向的10个值。您可以修改double和10以获得所需的类型/数量。 - Andrew Hundt从Xcode 8.0开始,lldb有了一个新的内置parray命令。因此,您可以输入以下内容:
(lldb) parray <COUNT> <EXPRESSION>
将指向EXPRESSION
结果的内存打印为该表达式指向类型的COUNT
个元素数组。
如果计数存储在当前帧中可用的变量中,则请记住您可以执行以下操作:
(lldb) parray `count_variable` pointer_to_malloced_array
这是lldb的通用功能,任何用反引号括起来的lldb命令行参数都会被视为一个表达式,该表达式返回一个整数,然后该整数在命令执行之前替换为该参数。
command alias
来创建快捷方式。 - Jim Ingham""" 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 变量 长度":
(lldb) parray a 5
(double) *a = 0
(double) [1] = 0
(double) [2] = 1.14468
(double) [3] = 2.28936
(double) [4] = 3.43404
AttributeError: 'NoneType' object has no attribute 'FindVariable'
的错误。 - fpg1503使用 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]
这个例子假设 'pointer' 是一个由64个浮点数组成的数组:float pointer[64];
目前似乎还不支持该功能。
您可以使用内存读取函数(memory read / x),例如
(lldb) memory read -ff -c10 `test`
从该指针打印浮点数十次。 这应该与gdb的@具有相同的功能。
(lldb) memory read -ff -c10 \
test` ` - pmdjx/10f test
。 - wardw从Martin R的回答开始,我对其进行了改进,如下所示:
如果指针不是一个简单变量,例如:
struct {
int* at;
size_t size;
} a;
那么 "parray a.at 5" 将会失败。
我通过将 "FindVariable" 替换为 "GetValueForVariablePath" 来解决了这个问题。
现在,如果你的数组中的元素是聚合的呢,例如:
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”并检索其子元素来解决了这个问题。
添加了一个可选的“first”参数(用法:parray [FIRST] COUNT),当您拥有大量元素时非常有用。
在初始化时执行了“command script add -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')
lldb
(或者是Python)要求将first和count的赋值放在不同的行上。除此之外,这个代码很好用!感谢您的分享! - Kaelin ColclasureGetValueForVariablePath
返回的“无值”感兴趣。我正在Xcode 5.0中使用lldb-300.2.47。对于int array[8]
,parry array 8
返回“无值”,而print array [0]
按预期工作。 - NoahRGetValueForVariablePath
更换为 EvaluateExpression
,因为我仍然看到 No value
。现在这样的指针表达式可以正常工作:parray ((double*)sourcePointer+1) 5
。根据API文档,两个函数的返回类型相同,因此 EvaluateExpression
似乎更好些。 - NoahR我试图添加评论,但这对于发布完整答案并不好,所以我自己回答了。这解决了获取“无值”的问题。您需要获取当前帧,因为我认为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) + "]")
EvaluateExpression
的输出被分配给lldb变量,而数组索引没有被打印。因此,输出的行看起来像这样:
(double) $68 = 0
- NoahR要检查变量,您可以使用frame variable
命令(fr v
是最短的唯一前缀),该命令具有一个-Z
标志,可以完全满足您的需求:
(lldb) fr v buffer -Z5
(int64_t *) buffer = 0x000000010950c000 {
(int64_t) [0] = 0
(int64_t) [1] = 0
(int64_t) [2] = 0
(int64_t) [3] = 0
(int64_t) [4] = 0
}
不幸的是,expression
不支持那个标志。
那么在这种情况下,你可能不妨编写自己的自定义 C 函数并使用以下方式调用:
call (int)myprint(args)