1

This is a follow on question from my post a day ago: Writing a Python script to print out an array of recs in lldb

I am trying to write a Python script for use with lldb which will allow me to print out records of a given type which are pointed to by an array of void *'s. Using the Python which Jason provided yesterday (thanks for great advice), I am able to get an SBValue object which contains the void * for each member in the array.

Now I can't figure out how to create a new SBValue object which represents the record starting with the SBValue object which contains the void *. In the code below, I create an array of void *'s which each point to a TraceRec record.

In the Python below, I am trying to create a SBValue object which contains a TraceRec given a SBValue object which contains one of the elements (of type void *) in the array.

#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;
}

The Python code to print the second elements in fPointerArray is:

(lldb) br s -p break
(lldb) r
(lldb) scri
>>> debugger = lldb.debugger
>>> target = debugger.GetSelectedTarget()
>>> traceLog = target.FindFirstGlobalVariable("com_softraid_gTraceLogPtr")
>>> pointerArray = traceLog.GetChildMemberWithName("fPointerArray")
>>> voidPointer = pointerArray.GetChildAtIndex(1, lldb.eNoDynamicValues, 1)
>>> print voidPointer
(void *) [1] = 0xffffff807b602e10

But how do I access the contents of the TraceRec which is pointed to by voidPointer?

A note for anyone setting up lldb for 2 Mac debugging: You need to configure some settings in order to get lldb to load symbols correctly. I use the following file to initialize lldb (filename = .lldb_init in the home directory):

settings set target.load-script-from-symbol-file true

#   Load the symbols for all the kexts
settings set plugin.dynamic-loader.darwin-kernel.load-kexts true

#   Load the symbols from the kext being developed (from /R2D2/syms)
settings set platform.plugin.darwin-kernel.kext-directories /R2D2/syms

#   Import the Python scripts
command script import ./sr_debug_macros.py

#   Import lldb command aliases
command source ./sr_debug_macros

//  Wait for connection to the remote Mac
kdp-remote 10.0.1.15

I start my lldb session using the following command in Terminal:

xcrun lldb -s lldb_init
Community
  • 1
  • 1

1 Answers1

2

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)

There's also SBTarget::CreateValueFromAddress if you had a pointer to raw memory and wanted to cast it to a type. But in this case you're starting with an SBValue of the variable.

Jason Molenda
  • 14,835
  • 1
  • 59
  • 61
  • Thank you. I never would have been able to figure that out by myself. I have spent hours trying already. It makes a lot of sense now that I see it. – Tim Standing Feb 13 '14 at 05:55
  • Be careful with SBValue::Cast though - it's a sharp tool. The example Jason gave will work just fine because sizeof(void*) == sizeof(TraceRec*) - if you start casting to/from types with different sizes, the wrong thing might happen with truncation and whatnot. Hack on! – Enrico Granata Feb 13 '14 at 18:42