Подтвердить что ты не робот

Как напечатать переменную <неполный тип> в gdb

Иногда gdb печатает "неполный тип" для некоторых типов переменных. Что это значит и как мы можем видеть эту ценность?

4b9b3361

Ответ 1

Это означает, что тип этой переменной был не полностью определен. Например:

struct hatstand;
struct hatstand *foo;

GDB знает, что foo является указателем на структуру hatstand, но члены этой структуры не определены. Следовательно, "неполный тип".

Чтобы напечатать значение, вы можете применить его к совместимому типу.

Например, если вы знаете, что foo действительно является указателем на структуру lampshade:

print (struct lampshade *)foo

Или вы можете печатать его как общий указатель или рассматривать его так, как если бы оно было целым числом:

print (void *)foo
print (int)foo

См. также эти страницы из руководства GDB:

Ответ 2

Я обнаружил, что если вы разбираете функцию, которая использует неполный тип структуры, gdb "обнаруживает" элементы структуры и может впоследствии отображать их. Например, скажем, у вас строковая структура:

struct my_string {
    char * _string,
    int _size
} ;

некоторые функции для создания и получения строки с помощью указателя:

my_string * create_string(const char *) {...}
const char * get_string(my_string *){...}

и тест, который создает строку:

int main(int argc, char *argv[]) {
    my_string *str = create_string("Hello World!") ;
    printf("String value: %s\n", get_string(str)) ;
    ...
}

Запустите его в gdb и попробуйте 'print * str', и вы получите ответ "неполного типа". Однако попробуйте "разобрать get_string", а затем "print * str", и он правильно отобразит структуру и значения. Я понятия не имею, почему это работает, но это так.

Ответ 3

У меня была та же проблема. Если вы загружаете символы из своих библиотек вручную:

set auto-solib-add off
attach thread_id
shared any_lib
shared another_lib

Вам нужно загрузить символы из библиотеки, где этот объект объявлен, с той же командой.

Ответ 4

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

Мой пример:

В .h для класса этот класс включал объявление вперед внутреннего вспомогательного класса, чтобы внешний класс мог содержать указатель на него. Соответствующий .cpp имел полное определение внутреннего вспомогательного класса.

При разрыве метода внешнего класса gdb сообщил о неполном типе для разыменования указателя на внутренний экземпляр класса через экземпляр внешнего класса.

Выдавая команду дизассемблирования на один из методов во внешнем классе, разрешенный gdb понимает структуру внутреннего класса с использованием того же самого указателя, который ранее не удался.

Ответ 5

Dislamer

Я - разработчик на Python, обладающий лишь минимальными знаниями C++ и того, как функционирует ОС Linux, поэтому то, что я опишу ниже, является лишь моим решением проблемы, с которой я лично столкнулся.

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

пример

(gdb) info share Qt
From                To                  Syms Read   Shared Object Library
0x00007ffff5336080  0x00007ffff56ba585  Yes (*)     /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
0x00007ffff4ad3510  0x00007ffff4ef0cbe  Yes (*)     /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5
0x00007ffff47829c0  0x00007ffff47e1ba1  Yes (*)     /usr/lib/x86_64-linux-gnu/libQt5DBus.so.5
0x00007ffff40bb5e0  0x00007ffff439dd92  Yes (*)     /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
0x00007ffff2e581e0  0x00007ffff2e78e4f  Yes (*)     /usr/lib/x86_64-linux-gnu/libQt5Xml.so.5
0x00007ffff28c8a00  0x00007ffff29d9999  Yes (*)     /usr/lib/x86_64-linux-gnu/libQt5Network.so.5
0x00007ffff2251750  0x00007ffff2252a46  Yes (*)     /usr/lib/x86_64-linux-gnu/libQt5X11Extras.so.5
0x00007ffff1cc9f80  0x00007ffff1cfc861  Yes (*)     /usr/lib/x86_64-linux-gnu/libQt5PrintSupport.so.5
0x00007fffee269c10  0x00007fffee297b57  Yes (*)     /usr/lib/x86_64-linux-gnu/libQt5Svg.so.5
0x00007fffed987560  0x00007fffed98b6a8  Yes (*)     /usr/lib/x86_64-linux-gnu/libQt5TextToSpeech.so.5
0x00007fffe980e130  0x00007fffe9900c0c  Yes (*)     /usr/lib/x86_64-linux-gnu/libQt5XcbQpa.so.5
0x00007fffe69ef650  0x00007fffe69ffe0d  Yes (*)     /usr/lib/x86_64-linux-gnu/libQt5QuickControls2.so.5
0x00007fffe5c0f890  0x00007fffe5eae1c1  Yes (*)     /usr/lib/x86_64-linux-gnu/libQt5Quick.so.5
0x00007fffe5522690  0x00007fffe581f636  Yes (*)     /usr/lib/x86_64-linux-gnu/libQt5Qml.so.5
0x00007fffe51996b0  0x00007fffe5221363  Yes (*)     /usr/lib/x86_64-linux-gnu/libQt5QuickTemplates2.so.5
(*): Shared library is missing debugging information.

^ во всех библиотеках Qt в текущем примере отсутствует отладочная информация. Это связано с тем, что отладочная информация для библиотек qt поставляется в отдельных пакетах, которые не устанавливаются.

Всякий раз, когда я сделал whatis все работало хорошо:

(gdb) whatis e
type = QEvent *

но когда я попытался получить доступ к членам

(gdb) p e->type()
Couldn't find method QEvent::type

и пытается получить подробное описание типа

(gdb) ptype e
type = class QEvent {
  <incomplete type>
} *

Решение (для Qt на Ubuntu)

  1. Найдите, к какому пакету в вашем дистрибутиве ОС принадлежит файл
$ dpkg -S /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
libqt5core5a:amd64: /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
  1. Поиск связанных пакетов

    Поиск с помощью ключа libqt5core5a вернул 2 пакета, один из них - сама libqt5core5a, а другой - libqt5core5a-dbgsym. Описание для последнего говорит: "символы отладки для libqt5core5a"

  2. Установить пакеты с символами отладки (я также установил символы отладки для некоторых других важных библиотек Qt)

$ sudo apt install libqt5core5a-dbgsym libqt5widgets5-dbgsym libqt5gui5-dbgsym
  1. Убедитесь, что в gdb библиотеки теперь имеют отладочную информацию
(gdb) info share Qt
From                To                  Syms Read   Shared Object Library
0x00007ffff5336080  0x00007ffff56ba585  Yes         /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
0x00007ffff4ad3510  0x00007ffff4ef0cbe  Yes         /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5
0x00007ffff47829c0  0x00007ffff47e1ba1  Yes (*)     /usr/lib/x86_64-linux-gnu/libQt5DBus.so.5
0x00007ffff40bb5e0  0x00007ffff439dd92  Yes         /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
0x00007ffff2e571e0  0x00007ffff2e77e4f  Yes (*)     /usr/lib/x86_64-linux-gnu/libQt5Xml.so.5
0x00007ffff28c7a00  0x00007ffff29d8999  Yes (*)     /usr/lib/x86_64-linux-gnu/libQt5Network.so.5
0x00007ffff2250750  0x00007ffff2251a46  Yes (*)     /usr/lib/x86_64-linux-gnu/libQt5X11Extras.so.5
0x00007ffff1cc8f80  0x00007ffff1cfb861  Yes (*)     /usr/lib/x86_64-linux-gnu/libQt5PrintSupport.so.5
0x00007fffee268c10  0x00007fffee296b57  Yes (*)     /usr/lib/x86_64-linux-gnu/libQt5Svg.so.5
0x00007fffed985560  0x00007fffed9896a8  Yes (*)     /usr/lib/x86_64-linux-gnu/libQt5TextToSpeech.so.5
0x00007fffe95fc130  0x00007fffe96eec0c  Yes (*)     /usr/lib/x86_64-linux-gnu/libQt5XcbQpa.so.5
0x00007fffe701f650  0x00007fffe702fe0d  Yes (*)     /usr/lib/x86_64-linux-gnu/libQt5QuickControls2.so.5
0x00007fffe623c890  0x00007fffe64db1c1  Yes (*)     /usr/lib/x86_64-linux-gnu/libQt5Quick.so.5
0x00007fffe5b4f690  0x00007fffe5e4c636  Yes (*)     /usr/lib/x86_64-linux-gnu/libQt5Qml.so.5
0x00007fffe57c66b0  0x00007fffe584e363  Yes (*)     /usr/lib/x86_64-linux-gnu/libQt5QuickTemplates2.so.5
(*): Shared library is missing debugging information.
  1. Теперь работа с типами Qt работает как положено
(gdb) p e->type()
$4 = QEvent::Paint
(gdb) ptype e
type = class QEvent {
  public:
...
}