Иногда gdb печатает "неполный тип" для некоторых типов переменных. Что это значит и как мы можем видеть эту ценность?
Как напечатать переменную <неполный тип> в gdb
Ответ 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)
- Найдите, к какому пакету в вашем дистрибутиве ОС принадлежит файл
$ dpkg -S /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
libqt5core5a:amd64: /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
-
Поиск связанных пакетов
Поиск с помощью ключа
libqt5core5a
вернул 2 пакета, один из них - самаlibqt5core5a
, а другой -libqt5core5a-dbgsym
. Описание для последнего говорит: "символы отладки для libqt5core5a" -
Установить пакеты с символами отладки (я также установил символы отладки для некоторых других важных библиотек Qt)
$ sudo apt install libqt5core5a-dbgsym libqt5widgets5-dbgsym libqt5gui5-dbgsym
- Убедитесь, что в
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.
- Теперь работа с типами Qt работает как положено
(gdb) p e->type()
$4 = QEvent::Paint
(gdb) ptype e
type = class QEvent {
public:
...
}