使用 LLDB API 获取使用 ARM-GCC 编译的 elf 文件中表达式的地址
Posted
技术标签:
【中文标题】使用 LLDB API 获取使用 ARM-GCC 编译的 elf 文件中表达式的地址【英文标题】:Using LLDB API to get the address of an expression in an elf file compiled with ARM-GCC 【发布时间】:2021-03-21 00:29:30 【问题描述】:假设 ARM .elf 文件在 .cpp 文件中具有嵌套结构,我可以使用 LLDB 计算表达式以获取全局结构/数组元素的地址。
lldb my_arm.elf
(lldb) ex &user_data.sub_type[2].i[3]
这给出了预期的结果,
(int *) $1 = 0x200001f0
...类似于 gdb,具有类型、索引和 RAM 中的地址,用于指定的 C/C++ 结构元素。 LLDB 还可以评估像 '&main'、'1+1' 等表达式。
尝试使用 lldb API 中的 EvaluateExpression() 在 python 中做同样的事情,总是会导致 !IsValid()。
import lldb # this works in python in linux.
dbg = lldb.SBDebugger().Create()
dbg.SetAsync(False)
modspec = lldb.SBModuleSpec()
modspec.SetFileSpec(lldb.SBFileSpec("my_arm.elf"))
modspec.SetSymbolFileSpec(lldb.SBFileSpec("my_arm.elf"))
target.AddModule(modspec) # target.IsValid() is True.
val=target.EvaluateExpression('&user_data.sub_type[2].i[3]')
这是 lldb 的 Python 外部。 val.IsValid()
始终为 False,我似乎无法从表达式中获取值。 '&main' 和 '1+1' 等更简单的表达式给出了类似的结果。
如何使用 lldb API 评估 .elf 文件的表达式?
【问题讨论】:
看起来您正在尝试评估没有正在运行的进程的表达式。表达式求值器确实有一个解释器模式,当没有正在运行的进程时它会回退,但这不是表达式求值器的主要模式。如果要查看全局数据target var
是首选模式。它还支持子元素和数组访问,但当然不调用函数或做任何需要在目标进程中执行代码的事情。此外,SBValue 有一个 SBError (SBValue.GetError()),它会告诉你表达式失败的原因。
Jim Ingham,是的,我正在尝试在不运行进程的情况下评估表达式。这些表达式通常用于交叉编译的 .elf 文件,因此运行该过程是不可行或不必要的。显然,.elf 文件具有在不运行进程的情况下评估这些表达式的必要信息——lldb 可以做到这一点,但我的努力是弄清楚如何让 API 做同样的事情。感谢您的建议。
【参考方案1】:
如此接近。您的程序的这种简化提供了预期的结果。
import lldb
dbg = lldb.SBDebugger().Create()
target = dbg.CreateTarget("my_arm.elf")
val = target.EvaluateExpression("&user_data.sub_type[2].i[3]")
print("'0', type=1, name=2, value=3, result=4".format(val, val.type, val.name, val.value, val.GetError()))
结果是:
'(int *) $0 = 0x200001f0', type=int *, name=$0, value=0x200001f0, result=success
...这与 gdb 给出的结果相似,但包含更多关于评估的表达式值的信息,并且使用 lldb 库在进程中快速完成。
【讨论】:
以上是关于使用 LLDB API 获取使用 ARM-GCC 编译的 elf 文件中表达式的地址的主要内容,如果未能解决你的问题,请参考以下文章