解除对lldb Python脚本中类型为void*的SBValue的引用

解除对lldb Python脚本中类型为void*的SBValue的引用,python,macos,kernel,remote-debugging,lldb,Python,Macos,Kernel,Remote Debugging,Lldb,这是我一天前发帖的后续问题: 我正在尝试编写一个用于lldb的Python脚本,它将允许我打印出由void*数组指向的给定类型的记录。使用Jason昨天提供的Python(感谢您的宝贵建议),我能够获得一个SBValue对象,其中包含数组中每个成员的void* #include <stdio.h> #include <stdlib.h> #include <stdint.h> typedef struct { int datum; } TraceR

这是我一天前发帖的后续问题:

我正在尝试编写一个用于lldb的Python脚本,它将允许我打印出由
void*
数组指向的给定类型的记录。使用Jason昨天提供的Python(感谢您的宝贵建议),我能够获得一个
SBValue
对象,其中包含数组中每个成员的
void*

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

typedef struct
{
    int datum;
} TraceRec;

typedef struct
{
    uint32_t fMaxNumberEntries;
    uint32_t fNextEntryNumber;
    void ** fPointerArray;
} com_softraid_TraceLog;

com_softraid_TraceLog *com_softraid_gTraceLogPtr;

int main ()
{
    com_softraid_TraceLog log;
    TraceRec * traceRecArray;

    traceRecArray = (TraceRec *) malloc (sizeof (TraceRec) * 100);

    traceRecArray[0].datum = 0;
    traceRecArray[1].datum = 1;
    traceRecArray[2].datum = 2;
    traceRecArray[3].datum = 3;

    com_softraid_gTraceLogPtr = &log;
    log.fMaxNumberEntries = 100;
    log.fNextEntryNumber = 4;

    log.fPointerArray = malloc (sizeof(void *) * 100);

    for (uint32_t index = 0; index < 100; index++)
    {
        log.fPointerArray[index] = &traceRecArray[index];
    }

    puts ("break here");

    return 0;
}
现在我不知道如何创建一个新的
SBValue
对象,该对象表示从包含void*的
SBValue
对象开始的记录。在下面的代码中,我创建了一个
void*
数组,每个数组指向一个TraceRec记录

在下面的Python中,我试图创建一个
SBValue
对象,该对象包含一个
TraceRec
,给定一个
SBValue
对象,该对象包含数组中的一个元素(类型为
void*

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

typedef struct
{
    int datum;
} TraceRec;

typedef struct
{
    uint32_t fMaxNumberEntries;
    uint32_t fNextEntryNumber;
    void ** fPointerArray;
} com_softraid_TraceLog;

com_softraid_TraceLog *com_softraid_gTraceLogPtr;

int main ()
{
    com_softraid_TraceLog log;
    TraceRec * traceRecArray;

    traceRecArray = (TraceRec *) malloc (sizeof (TraceRec) * 100);

    traceRecArray[0].datum = 0;
    traceRecArray[1].datum = 1;
    traceRecArray[2].datum = 2;
    traceRecArray[3].datum = 3;

    com_softraid_gTraceLogPtr = &log;
    log.fMaxNumberEntries = 100;
    log.fNextEntryNumber = 4;

    log.fPointerArray = malloc (sizeof(void *) * 100);

    for (uint32_t index = 0; index < 100; index++)
    {
        log.fPointerArray[index] = &traceRecArray[index];
    }

    puts ("break here");

    return 0;
}
但是如何访问由
voidPointer
指向的
TraceRec
的内容呢

任何设置lldb进行2 Mac调试的人都需要注意:为了让lldb正确加载符号,您需要配置一些设置。我使用以下文件初始化lldb(主目录中的filename=
.lldb_init
):

我在终端中使用以下命令启动lldb会话:

xcrun lldb -s lldb_init

SBTarget::FindFirstType
SBValue::Cast

>>> print target.FindFirstType("TraceRec").GetPointerType()
TraceRec *
>>> tracerec_ptr = target.FindFirstType("TraceRec").GetPointerType()

>>> print voidPointer.Cast(tracerec_ptr)
(TraceRec *) [1] = 0x0000000100103a94
>>> print voidPointer.Cast(tracerec_ptr).Dereference()
(TraceRec) *[1] = (datum = 1)

如果您有一个指向原始内存的指针,并希望将其强制转换为类型,那么还有一个
SBTarget::CreateValueFromAddress
。但在本例中,您将从变量的
SBValue
开始。

谢谢。我自己永远也不可能弄明白这一点。我已经试了好几个小时了。现在我看到它很有道理。但是要小心SBValue::Cast-它是一个锋利的工具。Jason给出的示例可以很好地工作,因为sizeof(void*)==sizeof(TraceRec*)-如果您开始对不同大小的类型进行强制转换,截断之类的操作可能会发生错误。继续!
>>> print target.FindFirstType("TraceRec").GetPointerType()
TraceRec *
>>> tracerec_ptr = target.FindFirstType("TraceRec").GetPointerType()

>>> print voidPointer.Cast(tracerec_ptr)
(TraceRec *) [1] = 0x0000000100103a94
>>> print voidPointer.Cast(tracerec_ptr).Dereference()
(TraceRec) *[1] = (datum = 1)