2016-05-11 2 views
1

После вопроса здесь: Writing a Python script to print out an array of recs in lldbпечать структура массива в lldb питона

Я хотел бы быть в состоянии создать резюме типа для массива данной структуры в lldb. Проблема в том, что я не могу правильно обращаться к массиву через python-lldb. Некоторые данные неверны.

У меня есть следующий код теста в C:

#include <stdio.h> 
#include <stdlib.h> 

struct Buffer 
{ 
    struct Buffer* next; 
    struct Buffer* prev; 
}; 

struct Base 
{ 
    struct Buffer* buffers; 
    int count; 
}; 

void fill(struct Buffer* buf, int count) 
{ 
    for (int i = 0; i < count; ++i) 
    { 
     struct Buffer t = {(void*)0xdeadbeef,(void*)i}; 
     buf[i] = t; 
    } 
} 

void foo(struct Base* base) 
{ 
    printf("break here\n"); 
} 

int main(int argc, char** argv) 
{ 
    int c = 20; 
    void* buf = malloc(sizeof (struct Buffer) * c); 
    struct Base base = {.buffers = buf, .count = c}; 
    fill(base.buffers, base.count); 
    foo(&base); 
    return 0; 
} 

В lldb:

(lldb) b foo 
(lldb) r 
(lldb) script 
>>> debugger=lldb.debugger 
>>> target=debugger.GetSelectedTarget() 
>>> frame=lldb.frame 
>>> base=frame.FindVariable('base') 
>>> buffers=base.GetChildMemberWithName('buffers') 

Теперь buffers должен указывать на массив struct Buffer, и я должен быть в состоянии получить доступ к каждому и каждый Buffer через функцию buffers.GetChildAtIndex, но данные повреждены в первых двух пунктах.

>>> print buffers.GetChildAtIndex(0,0,1) 
(Buffer *) next = 0x00000000deadbeef 
>>> print buffers.GetChildAtIndex(1,0,1) 
(Buffer *) prev = 0x0000000000000000 
>>> print buffers.GetChildAtIndex(2,0,1) 
(Buffer) [2] = { 
    next = 0x00000000deadbeef 
    prev = 0x0000000000000002 
} 

Только buffers[2] и все пункты в порядке.

Почему print buffers.GetChildAtIndex(1,0,1) указывает на buffers[0].count товар вместо buffers[1]?

Что я делаю неправильно?

ответ

1

GetChildAtIndex пытается быть немного более полезным для ваших целей здесь. Это согласуется с помощью, которая гласит:

Указатели отличаются в зависимости от того, на что они указывают. Если указатель указывает на простой тип, то дочерний индекс является единственным дочерним значением, доступным только для синтетического значения , в этом случае указатель будет использоваться как массив и может создавать «синтетические» дочерние значения, используя положительные или отрицательные индексы. Если указатель указывает на агрегированный тип (массив, класс, объединение, структура), то плательщик прозрачно пропустит, и любые дочерние объекты станут индексами дочерних значений в сводном типе. Например, если у нас есть тип «Точка», и у нас есть SBValue, который содержит указатель на тип «Точка», тогда ребенок с нулевым индексом будет членом «x», а дочерний элемент с индексом 1 будет членом 'y' (ребенок с нулевым индексом не будет экземпляром «Point»).

Итак, буферы.GetChildAtIndex (2,0,1) должны были вернуть «Нет значения». Либо это, либо передача 1 для аргумента allow-синтез должны отключить это поведение заглядывания. В любом случае, это ошибка, пожалуйста, напишите ее http://bugreporter.apple.com.

В то же время вы можете получить тот же эффект, пройдя свой массив вручную и используя «SBTarget.CreateValueFromAddress» для создания значений. Начните с получения адреса массива с буферами. GetAddress(); размер буферов, получив тип буферов, получив свой тип Pointee &, вызывающий GetByteSize, а затем просто увеличивайте адрес по времени подсчета размера, чтобы создать все значения.

+0

Спасибо, а в качестве примечания: глядя на http://bugreporter.apple.com? Последняя ошибка, с которой я открылся, не обрабатывался более года. – mrdvlpr

+0

Ошибки от репортера ошибок раздаются командам, ответственным в довольно коротком порядке. Что происходит после этого больше зависит от команда получает ошибку. –

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