编写Python脚本以输出lldb中的recs数组 [英] Writing a Python script to print out an array of recs in lldb

查看:90
本文介绍了编写Python脚本以输出lldb中的recs数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要有关lldb Python模块中使用的SBValue class的帮助,该模块用于创建lldb调试会话的脚本.

I need help with the SBValue class used in the lldb Python module which is used for creating scripts for lldb debugging sessions.

我正在将我的kext测试和调试系统从gdb移植到lldb,因此我可以开始使用最新版本的XcodeMac OS 10.9.1.此过程的一部分是用python重写我的gdb调试脚本,以便它们可与lldb一起使用.

I am in the process of porting my kext test and debug system from gdb to lldb so I can start using the latest version of Xcode and Mac OS 10.9.1. Part of this process is rewriting my gdb debug scripts in python so they can be used with lldb.

我有两个Mac设置,可以放入lldb并在受害Mac的内核中四处探寻.我还可以在运行lldb会话时调用我的Python脚本.我陷入了困境,尽管我无法弄清楚如何显示记录数组的内容.

I have the two mac setup working, can drop into lldb and poke around in the kernel of the victim Mac. I can also my Python script to be called when I am running an lldb session. I'm stuck though in that I am unable to figure out how to display the contents of an array of records.

例如,给定一个TraceRecs数组:

typedef struct
{

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

一个包含跟踪记录数组的类

a class which holds an array of trace records

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

以及内核中的全局变量,它指向此类的对象:

and a global in the kernel which points to an object of this class:

extern com_softraid_TraceLog * com_softraid_gTraceLogPtr;

我可以使用以下Python脚本获取lldb中com_softraid_gTraceLogPtr的值:

I can use the following Python script to get the value of com_softraid_gTraceLogPtr in 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类中的大多数方法,但是没有任何运气.

but I can't figure out how to display the values in fields of any of records in the array. I have tried most of the methods in the SBValue class without any luck.

有人知道这应该如何工作吗?任何帮助都会很棒.

Does anyone understand how this is supposed to work? Any help would be great.

P. S .:如果其他人试图使它正常工作,那么第一步应该是更新到Xcode 5.1 b5. Xcode 5.1 b3附带的lldb版本在显示IOKit类的内容子类时经常崩溃.

P. S.: If anyone else is trying to get this to work, the first step should be to update to Xcode 5.1 b5. The version of lldb which ships with Xcode 5.1 b3 crashes frequently when displaying the contents subclasses of IOKit classes.

推荐答案

您正在寻找SBValue::GetChildAtIndex(),但需要使用该API的长格式.例如,对于独立的用户进程C文件,

You're looking for SBValue::GetChildAtIndex() but you need to use the long form of that API. For instance, with a standalone user process C file,

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

我们可以在交互式脚本模式下进行一些实验:

we can experiment a little in the interactive script mode:

(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对象中数组每个成员的原始字节,但是您需要将这些字节强制返回到您的结构中,这样我就不会那样做.

There's also SBValue::GetPointeeData() which would give you the raw bytes of each member of the array in an SBData object but then you'd need to coerce those bytes back into your structure so I wouldn't go that way.

这篇关于编写Python脚本以输出lldb中的recs数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆