Заставить LLDB переинтерпретировать адрес как указатель на объект, тип которого является экземпляром шаблона.

При отладке у меня есть адрес в памяти и я знаю тип объекта, который находится по этому адресу, и я хочу, чтобы отладчик отображал этот экземпляр объекта. Это можно сделать с помощью команды печати для типов, которые не являются шаблонами, но, по-видимому, не работает для типов, которые являются экземпляром шаблона.

См. этот пример кода:

template<typename T>
class X
{
public:
    X() {
        printf("a\n");
    }
};

class Y
{
public:
    Y() {
        printf("a\n");
    }
};



int main(void)
{
    X<int> x;
    Y y;

    return 1;
}

когда я запускаю программу, ломаюсь в main и пытаюсь интерпретировать случайный действительный адрес в указатели на объекты X и Y, первый терпит неудачу:

(lldb) p *(Y*)0x0000000100000ee6
(Y) $0 = {}
(lldb) p *(X<int>*)0x0000000100000ee6
warning: could not load any Objective-C class information. This will significantly reduce the quality of type information available.
error: use of undeclared identifier 'X'
error: expected '(' for function-style cast or type construction
error: expected expression

Есть ли способ сделать это в lldb? (изменить: Mac OS X lldb-360.1.65 и lldb-310.2.37)


person Natris    schedule 04.11.2016    source источник


Ответы (1)


Отладочная информация для C++ в настоящее время не представляет шаблоны в абстрактном виде, она говорит только о конкретных экземплярах шаблонов, присутствующих в вашей программе. Но команда выражения lldb использует настоящий синтаксический анализатор C++ (clang), который при анализе выражения, подобного тому, который вы пробовали, хочет сначала увидеть X как абстрактный шаблон. Поскольку мы о них не знаем, мы не можем выполнить запрос типа clang для X, и поэтому ошибка, которую вы видите, это «необъявленный идентификатор X».

Вы можете обойти это, создав typedef для типов указателей, которые вы хотите привести таким образом. Это не очень удовлетворительно, потому что вы должны сделать это заранее, И вы должны использовать typedef где-то в своем коде, потому что — чтобы сохранить размер отладочной информации управляемым — clang не выдает отладочную информацию для типов, которые не являются использовал. Но это работает, например. Я добавляю к вашему примеру кода:

typedef X<int> * x_int_ptr;

а затем позже в основном:

  x_int_ptr bar = (x_int_ptr) &x;

чтобы убедиться, что он записан, то в ldb я могу сделать:

(lldb) expr *((x_int_ptr) 0x00007fff5fbff798)
(X<int>) $1 = {}
person Jim Ingham    schedule 04.11.2016