2014-02-11 80 views
1

我需要關於lldb Python模塊中使用的SBValue class的幫助,該模塊用於爲lldb調試會話創建腳本。編寫一個Python腳本以便在lldb中打印一個rec數組

我在移植我的kext測試和調試系統從gdblldb這樣我就可以開始使用最新版本的XcodeMac OS 10.9.1的過程。這個過程的一部分是在python中重寫我的gdb調試腳本,以便它們可以與lldb一起使用。

我有兩個mac設置工作,可以放入lldb並在受害者Mac的內核中徘徊。我還可以在運行lldb會話時調用我的Python腳本。我卡住了,但我無法弄清楚如何顯示記錄數組的內容。

例如,給定的TraceRecs數組:

typedef struct 
{ 

    mach_timespec_t timeStamp; 
    thread_t thread; 
    TraceRecordType recordType; 
    char entry[kEntrySize]; 
} TraceRec; 

持有的跟蹤記錄

class com_softraid_TraceLog 
{ 
    private: 
     UInt32 fMaxNumberEntries; 
     UInt32 fNextEntryNumber; 
     TraceRec * fTraceRecArray; 
     . 
     . 
     . 

,並在指向這個類的一個對象內核全局數組類:

extern com_softraid_TraceLog * com_softraid_gTraceLogPtr; 

我可以使用下面的Python腳本來獲取com_so的值ftraid_gTraceLogPtr在LLDB:

#! /usr/bin/env python 
# -*- coding: utf-8 -*- 

import lldb 
import commands 
import optparse 
import shlex 

def __lldb_init_module(debugger, internal_dict): 
    debugger.HandleCommand('command script add -f sr_debug_macros.srtrace srtrace') 

def srtrace(debugger, user_input, result, internal_dict): 
    """srtrace [number_entries] dump out that number of entries, default = 0 = all entries""" 

    target = debugger.GetSelectedTarget() 
    traceLog = target.FindFirstGlobalVariable("com_softraid_gTraceLogPtr") 
    traceRecordArray = traceLog.GetChildMemberWithName("fTraceRecArray") 
    maxNumberEntries = traceLog.GetChildMemberWithName("fMaxNumberEntries").GetValueAsUnsigned() 
    nextEntryNumber = traceLog.GetChildMemberWithName("fNextEntryNumber").GetValueAsUnsigned() 

    print >>result, "SRLog Current Entry: %d, Log Size: %d" % (nextEntryNumber, maxNumberEntries) 

    print >>result, traceRecordArray 

並且輸出是:

(lldb) srtrace 
SRLog Current Entry: 388, Log Size: 8192 
(TraceRec *) fTraceRecArray = 0xffffff80a48fd000 

,但我不能找出如何在任何陣列中的記錄中的字段中顯示的值。我已經嘗試了SBValue類中的大多數方法,但沒有任何運氣。

有沒有人知道這應該如何工作?任何幫助都會很棒。

P. S .:如果其他人試圖讓這個工作,第一步應該是更新到Xcode 5.1 b5。顯示IOKit類的內容子類時,隨Xcode 5.1 b3一起提供的lldb版本頻繁崩潰。

回答

0

您正在尋找SBValue::GetChildAtIndex(),但您需要使用該API的長形式。例如,對於一個獨立的用戶進程的C文件,

#include <stdio.h> 
#include <stdlib.h> 
#include <stdint.h> 
typedef struct 
{ 
    int datum; 
} TraceRec; 

typedef struct 
{ 
     uint32_t fMaxNumberEntries; 
     uint32_t fNextEntryNumber; 
     TraceRec *fTraceRecArray; 
} com_softraid_TraceLog; 

com_softraid_TraceLog *com_softraid_gTraceLogPtr; 

int main() 
{ 
    com_softraid_TraceLog log; 
    com_softraid_gTraceLogPtr = &log; 
    log.fTraceRecArray = (TraceRec *) malloc (sizeof (TraceRec) * 100); 
    log.fMaxNumberEntries = 100; 
    log.fNextEntryNumber = 4; 
    log.fTraceRecArray[0].datum = 0; 
    log.fTraceRecArray[1].datum = 1; 
    log.fTraceRecArray[2].datum = 2; 
    log.fTraceRecArray[3].datum = 3; 

    puts ("break here"); 

    return 0; 
} 

我們可以嘗試一點點在交互式腳本模式:

(lldb) br s -p break 
(lldb) r 
(lldb) scri 
>>> debugger = lldb.debugger 
>>> target = debugger.GetSelectedTarget() 
>>> traceLog = target.FindFirstGlobalVariable("com_softraid_gTraceLogPtr") 
>>> traceRecordArray = traceLog.GetChildMemberWithName("fTraceRecArray") 
>>> print traceRecordArray.GetChildAtIndex(1, lldb.eNoDynamicValues, 1) 
(TraceRec) [1] = { 
    datum = 1 
} 
>>> print traceRecordArray.GetChildAtIndex(2, lldb.eNoDynamicValues, 1) 
(TraceRec) [2] = { 
    datum = 2 
} 
>>> 

還有SBValue::GetPointeeData()這將使你的每個成員的原始字節這個數組在SBData對象中,但是你需要將這些字節強制回到你的結構中,所以我不會這麼做。

+0

當我嘗試時,我得到「沒有價值」(我完全輸入了你的行)。我可以打印traceRecordArray,但不能打印來自GetChildAtIndex() –

+0

Hm的結果,這與Xcode 5.0的lldb(lldb-300.2.53)一樣。我會仔細檢查你以後使用的Xcode - 但這裏的例子沒有隱藏我的袖子。我想不出你正在使用的lldb中的任何內容,這會導致行爲上的差異......可能還有別的事情發生,爲什麼它不適合你。只是要清楚 - 你在我上面寫的用戶進程測試文件上試過這個,它不起作用?或者在kext上? –

+0

我在遠程調試的kext上試了一下。兩款Mac都運行10.9.1。開發Mac運行Xcode 5.1 b5。我通過運行xcrun lldb -s lldb_init來啓動lldb(其中lldb_init是會話的初始化文件)。 lldb版本是:lldb-310.2.34。 –

相關問題