LLDB Python API类型转换

LLDB Python API类型转换,python,lldb,Python,Lldb,在GDB宏中,我可以执行以下操作: set $node = (node_t *) $arg0 当节点在库文件中实际定义时。如何在LLDB Python宏中执行相同性质的强制转换操作?有几种方法可以做到这一点。最简单的方法是使用SBFrame.EvaluateExpression,如: options = lldb.SBExpressionOptions() val = frame.EvaluateExpression("(node_t *) $arg1", options) 其中frame是

在GDB宏中,我可以执行以下操作:

set $node = (node_t *) $arg0

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

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

options = lldb.SBExpressionOptions()
val = frame.EvaluateExpression("(node_t *) $arg1", options)
其中frame是要在其上下文中计算表达式的堆栈帧

你也可以不用表达式,如果你经常这样做的话效率会更高

例如,如果您有地址和类型,则可以使用
SBTarget.CreateValueFromAddress
直接生成强制转换值。您可以使用
SBTarget.FindFirstType
查找类型


如果您感兴趣的值位于寄存器中,则可以从
SBFrame.FindRegister
获取其值,然后使用
SBValue.cast
对其进行强制转换。当将一个复杂类型转换为另一个复杂类型时,该转换函数并不总是起作用——您需要表达式解析器来实现这一点——但对于简单的C指针,它确实可以很好地工作。

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

options = lldb.SBExpressionOptions()
val = frame.EvaluateExpression("(node_t *) $arg1", options)
其中frame是要在其上下文中计算表达式的堆栈帧

你也可以不用表达式,如果你经常这样做的话效率会更高

例如,如果您有地址和类型,则可以使用
SBTarget.CreateValueFromAddress
直接生成强制转换值。您可以使用
SBTarget.FindFirstType
查找类型


如果您感兴趣的值位于寄存器中,则可以从
SBFrame.FindRegister
获取其值,然后使用
SBValue.cast
对其进行强制转换。当将一个复杂类型转换为另一个复杂类型时,该转换函数并不总是起作用-您需要表达式解析器来实现这一点-但是对于简单的C指针,它确实可以很好地工作。

谢谢。我只想澄清一件事,因为LLDB宏中的所有变量都是LLDB.SBValue类型,并且像llidb.SBValue()这样的操作。如果对象不存在,GetChildMemberWithName()只返回None,在将GDB宏1:1转换为等效的LLDB宏时,是否可以忽略所有强制转换操作?我不太清楚您的意思。你能给我举个例子吗?注意gdb的“set”命令有点混乱,因为它要么设置gdb内部变量,要么如果你设置的不是gdb变量,它会将表达式传递给gdb的表达式解析器,并使gdb成为表达式中使用的“便利变量”。在后一种情况下,它完全等同于将相同的表达式传递给“print”。在lldb中,我们不使lldb“settings”变量可用于表达式解析器,因此第一种用法没有真正意义。但除此之外,方便变量的语法基本相同。例如,如果我有一个GDB命令,它有一个语句:$node=(node_t*)$a,if$node->data do something。对于等效的LLDB转换,如果node.GetChildMemberWithName(“”),我会说node=a。我的问题是,就lldb API而言,node和a都是lldb.SBValue()类型。甚至有必要进行强制转换吗?在第一个示例中,您从寄存器值($arg0)开始,该值可能具有“unsigned long”类型。因此,如果您直接从该寄存器生成SBValue,它的类型将错误,GetChildMemberWithName(“数据”)将返回错误。SBValues是同时具有值(例如,指向被调试对象中的某个内存)和类型(请参见SBValue.GetType())的对象。所有的GetChildMember。。。呼叫工作与SBValue的类型无关。谢谢。我只想澄清一件事,因为LLDB宏中的所有变量都是LLDB.SBValue类型,并且像llidb.SBValue()这样的操作。如果对象不存在,GetChildMemberWithName()只返回None,在将GDB宏1:1转换为等效的LLDB宏时,是否可以忽略所有强制转换操作?我不太清楚您的意思。你能给我举个例子吗?注意gdb的“set”命令有点混乱,因为它要么设置gdb内部变量,要么如果你设置的不是gdb变量,它会将表达式传递给gdb的表达式解析器,并使gdb成为表达式中使用的“便利变量”。在后一种情况下,它完全等同于将相同的表达式传递给“print”。在lldb中,我们不使lldb“settings”变量可用于表达式解析器,因此第一种用法没有真正意义。但除此之外,方便变量的语法基本相同。例如,如果我有一个GDB命令,它有一个语句:$node=(node_t*)$a,if$node->data do something。对于等效的LLDB转换,如果node.GetChildMemberWithName(“”),我会说node=a。我的问题是,就lldb API而言,node和a都是lldb.SBValue()类型。甚至有必要进行强制转换吗?在第一个示例中,您从寄存器值($arg0)开始,该值可能具有“unsigned long”类型。因此,如果您直接从该寄存器生成SBValue,它的类型将错误,GetChildMemberWithName(“数据”)将返回错误。SBValues是同时具有值(例如,指向被调试对象中的某个内存)和类型(请参见SBValue.GetType())的对象。所有的GetChildMember。。。调用不使用SBValue的类型。