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

StackOverflow https://stackoverflow.com/questions/232744

  •  04-07-2019
  •  | 
  •  

Вопрос

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

Это было полезно?

Решение

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

struct hatstand;
struct hatstand *foo;

GDB знает это foo является указателем на hatstand структура, но члены этой структуры не определены.Отсюда и «неполный тип».

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

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

print (struct lampshade *)foo

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

print (void *)foo
print (int)foo

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

Другие советы

Я обнаружил, что если вы разберете функцию, которая использует неполный тип структуры, 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», и вы получите ответ «неполный тип». Тем не менее, попробуйте 'disassemble get_string', а затем 'print * str', и он будет правильно отображать структуру и значения. Я понятия не имею, почему это работает, но это работает.

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

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

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

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

Мой пример:

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

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

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

Дисламер

Я разработчик 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:
...
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top