【问题标题】:LLDB Python API type castingLLDB Python API 类型转换
【发布时间】:2016-06-27 17:49:09
【问题描述】:

在 GDB 宏中,我可以这样做:

set $node = (node_t *) $arg0

当 node_t 实际定义在库文件中时。如何在 LLDB Python 宏中进行相同性质的转换操作?

【问题讨论】:

    标签: python lldb


    【解决方案1】:

    有几种方法可以做到这一点。最简单的方法是使用 SBFrame.EvaluateExpression,例如:

    options = lldb.SBExpressionOptions()
    val = frame.EvaluateExpression("(node_t *) $arg1", options)
    

    其中 frame 是您在其上下文中评估表达式的堆栈帧。

    您也可以不使用表达式来执行此操作,如果您要经常执行此操作,效率会更高。

    例如,如果你有一个地址和一个类型,那么你可以使用SBTarget.CreateValueFromAddress 直接产生转换值。您可以使用SBTarget.FindFirstType 查找类型。

    如果你感兴趣的值在一个寄存器中,你可以从SBFrame.FindRegister获取它的值,然后用SBValue.Cast进行转换。将一种复杂类型转换为另一种复杂类型时,Cast 函数并不总是有效 - 您需要表达式解析器 - 但对于简单的 C 指针,它确实可以正常工作。

    【讨论】:

    • 谢谢。我只是想澄清一件事,因为 LLDB 宏中的所有变量都是 lldb.SBValue 类型,如果对象不存在,像 llidb.SBValue().GetChildMemberWithName() 这样的操作只会返回 None,是否有可能在将 GDB 宏 1:1 转换为等效的 LLDB 宏时忽略所有强制转换操作?
    • 不太清楚我明白你的意思。可以举个例子吗?
    • 请注意,gdb 的“set”命令有点混乱,因为它要么设置一个 gdb 内部变量,要么如果你设置的东西不是 gdb 变量,它会将表达式传递给 gdb 的表达式解析器并使 gdb “方便变量”用于表达式。在后一种情况下,它完全等同于将相同的表达式传递给“print”。在 lldb 中,我们没有使 lldb “设置”变量可用于表达式解析器,因此第一次使用并没有真正意义。但除此之外,便利变量的语法几乎相同。
    • 例如,如果我有一个包含以下语句的 GDB 命令:$node = (node_t *) $a, if $node->data 做某事。对于等效的 LLDB 翻译,我会说 node = a, if node.GetChildMemberWithName('')。我的问题是,就 lldb API 而言, node 和 a 都是 lldb.SBValue() 类型。是否有任何铸造的必要性?
    • 在您的第一个示例中,您从一个寄存器值 ($arg0) 开始 - 它的类型可能为“unsigned long”。因此,如果您直接从该寄存器中创建了一个 SBValue,它将具有错误的类型,并且 GetChildMemberWithName("data") 将返回一个错误。 SBValue 是同时具有值​​(例如,指向被调试者中的某些内存)和类型(参见 SBValue.GetType())的对象。所有 GetChildMember... 调用都与 SBValue 的类型无关。
    猜你喜欢
    • 1970-01-01
    • 2011-01-23
    • 1970-01-01
    • 2021-11-14
    • 2015-06-09
    • 2017-10-23
    • 1970-01-01
    相关资源
    最近更新 更多