在 LLDB 中查看数组:相当于 Xcode 4.1 中 GDB 的“@”运算符
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7062173/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
View array in LLDB: equivalent of GDB's '@' operator in Xcode 4.1
提问by midinastasurazz
I would like to view an array of elements pointed to by a pointer. In GDB this can be done by treating the pointed memory as an artificial array of a given length using the operator '@' as
我想查看一个指针指向的元素数组。在 GDB 中,这可以通过使用运算符“@”将指向的内存视为给定长度的人工数组来完成
*pointer @ length
where length
is the number of elements I want to view.
length
我想查看的元素数量在哪里。
The above syntax does not work in LLDB supplied with Xcode 4.1.
上述语法在 Xcode 4.1 提供的 LLDB 中不起作用。
Is there any way how to accomplish the above in LLDB?
有什么办法可以在 LLDB 中完成上述操作吗?
回答by Siyuan Ren
There are two ways to do this in lldb.
在 lldb 中有两种方法可以做到这一点。
Most commonly, you use the parray
lldb command which takes a COUNT
and an EXPRESSION
; EXPRESSION
is evaluated and should result in a pointer to memory. lldb will then print COUNT
items of that type at that address. e.g.
最常见的是,您使用parray
lldb 命令,它带有一个COUNT
和一个EXPRESSION
; EXPRESSION
被评估并且应该产生一个指向内存的指针。然后 lldb 将COUNT
在该地址打印该类型的项目。例如
parray 10 ptr
where ptr
is of type int *
.
哪里ptr
是类型int *
。
Alternatively, it can be done by casting the pointer to a pointer-to-array.
或者,它可以通过将指针转换为指向数组的指针来完成。
For example, if you have a int* ptr
, and you want to view it as an array of ten integers, you can do
例如,如果您有一个int* ptr
,并且您想将其视为一个包含十个整数的数组,您可以这样做
p *(int(*)[10])ptr
Because it relies only on standard C features, this method works without any plugins or special settings. It likewise works with other debuggers like GDB or CDB, even though they also have specialized syntaxes for printing arrays.
因为它只依赖于标准的 C 特性,所以这种方法不需要任何插件或特殊设置。它同样适用于 GDB 或 CDB 等其他调试器,即使它们也具有用于打印数组的专门语法。
回答by Jim Ingham
Starting with the lldb in Xcode 8.0, there is a new built-in parray command. So you can say:
从 Xcode 8.0 中的 lldb 开始,有一个新的内置 parray 命令。所以你可以说:
(lldb) parray <COUNT> <EXPRESSION>
to print the memory pointed to by the result of the EXPRESSION
as an array of COUNT
elements of the type pointed to by the expression.
将结果指向的内存打印为表达式所指向类型EXPRESSION
的COUNT
元素数组。
If the count is stored in a variable available in the current frame, then remember you can do:
如果计数存储在当前帧中可用的变量中,请记住您可以执行以下操作:
(lldb) parray `count_variable` pointer_to_malloced_array
That's a general lldb feature, any command-line argument in lldb surrounded in backticks gets evaluated as an expression that returns an integer, and then the integer gets substituted for the argument before command execution.
这是一个通用的 lldb 功能,lldb 中用反引号括起来的任何命令行参数都被评估为一个返回整数的表达式,然后在命令执行之前用整数替换参数。
回答by Martin R
The only way I found was via a Python scripting module:
我找到的唯一方法是通过 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)
Define a command "parray" in lldb:
在 lldb 中定义命令“parray”:
(lldb) command script import /path/to/parray.py
(lldb) command script add --function parray.parray parray
Now you can use "parray variable length":
现在您可以使用“parray可变长度”:
(lldb) parray a 5
(double) *a = 0
(double) [1] = 0
(double) [2] = 1.14468
(double) [3] = 2.28936
(double) [4] = 3.43404
回答by davidA
With Xcode 4.5.1 (which may or may not help you now), you can do this in the lldb console:
使用 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]
This example assumes that 'pointer' is an array of 64 floats: float pointer[64];
此示例假定 'pointer' 是一个包含 64 个浮点数的数组: float pointer[64];
回答by jng
Starting with Martin R answer I improved it as follow:
从 Martin R answer 开始,我对其进行了如下改进:
If the pointer is not a simple variable, e.g.:
struct { int* at; size_t size; } a;
Then "parray a.at 5" fails.
I fixed this by replacing "FindVariable" with "GetValueForVariablePath".
Now what if the elements in your array are aggregates, e.g.:
struct { struct { float x; float y; }* at; size_t size; } a;
Then "parray a.at 5" prints: a.at->x, a.at->y, a.at[2], a.at[3], a.at[4] because GetChildAtIndex() returns members of aggregates.
I fixed this by resolving "a.at" + "[" + str(i) + "]" inside the loop instead of resolving "a.at" and then retrieving its children.
Added an optional "first" argument (Usage: parray [FIRST] COUNT), which is useful when you have a huge number of elements.
Made it do the "command script add -f parray.parray parray" at init
如果指针不是一个简单的变量,例如:
struct { int* at; size_t size; } a;
然后“parray a.at 5”失败。
我通过用“GetValueForVariablePath”替换“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”
Here is my modified version:
这是我的修改版本:
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')
回答by w-m
It doesn't seem to be supported yet.
好像还没有支持。
You could use the memory read function (memory read / x), like
您可以使用内存读取功能(内存读取/ x),例如
(lldb) memory read -ff -c10 `test`
to print a float ten times from that pointer. This should be the same functionality as gdb's @.
从该指针打印浮点数十次。这应该与 gdb 的 @ 具有相同的功能。
回答by Dave Reed
I tried to add a comment but that wasn't great for posting a full answer so I made my own answer. This solves the problem with getting "No Value". You need to get the current frame as I believe lldb.frame is set at module import time so it doesn't have the current frame when you stop at a breakpoint if you load the module from .lldbinit. The other version would work if you import or reloaded the script when you stopped at the breakpoint. The version below should always work.
我尝试添加评论,但这对于发布完整答案并不好,所以我做出了自己的答案。这解决了获得“无价值”的问题。您需要获取当前帧,因为我相信 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) + "]")
回答by Holger
To inspect variables you can use the frame variable
command (fr v
is the shortest unique prefix) which has a -Z
flag which does exactly what you want:
要检查变量,您可以使用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
}
unfortunately expression
does not support that flag
不幸的expression
是不支持该标志
回答by Elektraglide
Well at that point, you may as well write your own custom C function and invoke it with:
那么在这一点上,您不妨编写自己的自定义 C 函数并使用以下命令调用它:
call (int)myprint(args)