2016-10-14 2 views
0

Если у меня есть структура вроде этого (в C)эквивалент питона gdb.execute ('...') в lldb

typedef struct { 
    int x; 
    int[2] y; 
} A; 

И экземпляр этого, скажем a с a.x=1 и a.y={2,3}.

Чтобы получить доступ к a.y[1] из сценариев python, действительно ли мне нужно выполнить эту очень полезную команду?

script print lldb.frame.FindVariable('a').GetChildMemberWithName('y').GetChildAtIndex(1) 

Я написал эту функцию, чтобы помочь мне, когда я хочу, чтобы напечатать членов структуры переменных в C:

# lldb_cmds.py 

import lldb 

def get_nested_val_c(vnames,idx=None): 
    """ 
     vnames is a list of strings ['a','b','c',...] that will be evaluated as if 
     you called 

      a.b.c.,... 

     So for [a,b,c] you get: 

      a.b.c 

     If idx is given, it is evaluated as 

      a.b.c[idx] 

    """ 

    try: 
     x=lldb.frame.FindVariable(vnames[0]) 
     for v_ in vnames[1:]: 
      x=x.GetChildMemberWithName(v_) 
    except TypeError: 
     x=lldb.frame.FindVariable(vnames) 

    if idx == None: 
     return x 

    try: 
     x=x.GetChildAtIndex(idx[0]) 
     for i_ in idx[1:]: 
      x=x.GetChildAtIndex(i_,False,True) 
    except TypeError: 
     x=x.GetChildAtIndex(idx) 

, который затем может быть загружен с

command script import lldb_cmds.py 

и называется (например, выше) с

python lldb_cmds.get_nested_val_c[['a','y'],1) 

Но есть ли более короткий путь? Да, я знаю, что вы можете написать

p a.y[1] 

, но так как там, кажется, не быть любой в то время как петли в lldb, как я мог напечатать это с переменным индексом, не прибегая к таким длинным заявлениям?

(И да, я знаю, что вы можете написать для этого примера: p *(int(*)[2])a.y, но я спрашиваю вообще.)

ответ

1

Я не совсем уверен, что вы хотите сделать здесь. Я отвечу на пару потенциальных вопросов, и вы можете сказать мне, был ли один из них прав ...

Если вы пытаетесь найти более удобный способ проникновения в известные вложенные структуры, это может быть более удобным : команды

var = lldb.frame.FindVariable("a").GetValueForExpressionPath("y[0]") 

Если то, что вы пытаетесь сделать, это запустить из командной строки в сценариях Python, есть два способа сделать это:

lldb.debugger.HandleCommand("command") 

это просто запускает команду, и выводит результаты lldb, или:

ret_val = lldb.SBCommandReturnObject() 
lldb.debugger.GetCommandInterpreter().HandleCommand("command", ret_val) 

Это приведет к выполнению команды и возвращает результат команды (которая является тем, что в драйвере lldb печатается при запуске команды) в объект ret_val. Это удобно, если вы хотите проверить результаты команды. Функция ReturnObject также сообщает вам, была ли команда успешной или нет, и содержит ошибку, если это не так.

Если вы пытаетесь напечатать статически выделенные массивы - как в вашем примере - вам не нужно делать бросок вам показать выше, вы просто должны быть в состоянии сделать:

(lldb) р ау

, и это должно печатать все элементы. Если вы имеете дело с массивами динамического размера (например, int *, которые вы указываете на массив malloc'ed), lldb в Xcode 8.0 имеет новую команду parray, которая позволит вам сказать:

(lldb) parray 10 a.y

для печати 10 элементов массива int, на которые указывает y.

 Смежные вопросы

  • Нет связанных вопросов^_^