2014-02-13 4 views
0

이 하루 전에 내 게시물에서 질문에 다음과 같습니다 Writing a Python script to print out an array of recs in lldblldb 파이썬 스크립트에서 형 무효 *의 인 SBValue를 역 참조

내가 수 lldb와 함께 사용하기위한 파이썬 스크립트를 작성하려고는 나는 void *의 배열에 의해 가리키는 주어진 유형의 레코드를 출력한다. 어제 제이슨이 제공 한 Python (큰 조언에 감사드립니다)을 사용하여 배열의 각 구성원에 대해 void *을 포함하는 SBValue 개체를 얻을 수있었습니다.

공백이 포함 된 SBValue 개체로 시작하는 레코드를 나타내는 새 SBValue 개체를 만드는 방법을 알아낼 수 없습니다. 아래의 코드에서는 각각이 TraceRec 레코드를 가리키는 void *의 배열을 만듭니다. 아래의 파이썬에서

, 나는 배열 (유형 void *의) 요소 중 하나를 포함하는 SBValue 오브젝트를 지정해 TraceRec를 포함하는 SBValue 객체를 생성하는 것을 시도하고있다.

(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 

하지만 어떻게 voidPointer에 의해 지시 된 TraceRec의 내용을 액세스합니까 :

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

이 fPointerArray의 두 번째 요소를 인쇄하는 파이썬 코드는?

lldb를 2 Mac 디버깅 용으로 설정하는 사람을위한 참고 사항 : lldb가 심볼을 올바르게로드하도록 설정하려면 몇 가지 설정을 구성해야합니다.

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 

내가 터미널에서 다음 명령을 사용하여 내 lldb 세션을 시작 : 나는 lldb (홈 디렉토리에있는 파일 이름 = .lldb_init)를 초기화하는 다음과 같은 파일을 사용

xcrun lldb -s lldb_init 

답변

0

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으로 시작합니다.

+0

감사합니다. 나는 혼자서 그것을 알아낼 수 없었을 것이다. 나는 이미 몇 시간을 보냈다. 나는 그것을 보았을 때 많은 의미가 있습니다. –

+0

SBValue :: Cast는 조심스럽게 다루십시오 - 예리한 도구입니다. sizeof (void *) == sizeof (TraceRec *) - 크기가 다른 유형으로 /에서 형변환을 시작하면 잘림 등으로 잘못된 것이 발생할 수 있습니다. 해킹! –