188 lines
7.8 KiB
Markdown
188 lines
7.8 KiB
Markdown
\~english \page debugging Debugging with GDB
|
||
\~russian \page debugging Отладка в GDB
|
||
|
||
\~english
|
||
|
||
PIP ships a GDB pretty-printer script, `tools/gdb/pip_pp.py`, that makes the basic types print their content instead of their raw internals:
|
||
|
||
| Type | Example output |
|
||
|------|----------------|
|
||
| \a PIString | `"hello"` |
|
||
| \a PIByteArray | `{0x48, 0x65, 0x6c, 0x6c, 0x6f}` |
|
||
| \a PIChar | `'a'` or `U+043c` |
|
||
| \a PIVector<T> | `{1, 2, 3}` |
|
||
| \a PIDeque<T> | `{1, 2, 3}` |
|
||
| \a PIStringList | `{"one", "two"}` |
|
||
| \a PIMap<K,V> | `{"x": 1, "y": 2}` |
|
||
| \a PISet<T> | `{3, 5}` |
|
||
| \a PIPair<K,V> | `{"k", 7}` |
|
||
| \a PIVariant | `PIVariant(pivInt, 4 bytes)` |
|
||
| \a PINetworkAddress | `192.168.1.10:8080` |
|
||
|
||
Nested containers are printed recursively, e.g. `PIVector<PIString>` prints as `{"a", "bb"}`.
|
||
Pointers to the covered types show the address and the content:
|
||
`(PIString *) 0x7fffffffdac0 "hello"`.
|
||
|
||
Printers are read-only and defensive: on any error GDB falls back to the
|
||
default (raw) printing. Long containers are truncated, only the first
|
||
32 elements are printed by default (the tail is shown as
|
||
`..., ... (N total)`); the limit is the `_MAX_ELEMENTS` constant at the
|
||
top of `pip_pp.py`.
|
||
|
||
Requirements: the executable and the PIP library must be built with debug
|
||
information (`-g`).
|
||
|
||
\section loading Loading the pretty-printers
|
||
|
||
Manual (works with any build tree):
|
||
|
||
\code{.gdb}
|
||
(gdb) source /path/to/pip/tools/gdb/pip_pp.py
|
||
\endcode
|
||
|
||
Run it after the executable is loaded (in a session started as
|
||
`gdb ./program`, or after the `file` command).
|
||
|
||
Automatic: CMake install places the script at
|
||
`<prefix>/share/pip/gdb/pip_pp.py` and an auto-load stub
|
||
`<prefix>/lib/libpip.so-gdb.py` next to the library. GDB evaluates the stub
|
||
automatically when libpip.so is loaded (see GDB manual, "Auto-loading
|
||
extensions"). If the library is installed outside of GDB's default auto-load
|
||
safe path, add the directory once:
|
||
|
||
\code{.gdb}
|
||
(gdb) add-auto-load-safe-path /your/prefix/lib
|
||
\endcode
|
||
|
||
Or create <homedir>/.gdbinit file and write to it next line
|
||
\code
|
||
add-auto-load-safe-path <root_dir>
|
||
\endcode
|
||
, where root_dir is top-level directory contains library and pip_pp.py script.
|
||
|
||
The stub is installed only for shared builds; for static builds
|
||
use the manual `source` command.
|
||
|
||
\section qtcreator Qt Creator
|
||
|
||
Qt Creator's Variables/Expressions views do not use GDB
|
||
pretty-printers; they run their own Python dumper. PIP provides the
|
||
dumper module `tools/qtcreator/pip_types.py`, which covers the same
|
||
types as `pip_pp.py`. To enable it:
|
||
|
||
1. Open the debugger settings (Qt Creator -> Settings -> Debugger).
|
||
2. Switch to the "Variables and expressions" tab.
|
||
3. In the "Extra dumper file" field (tooltip: "Path to a Python file
|
||
containing additional data dumpers"), enter the path to the file:
|
||
|
||
\code
|
||
/path/to/pip/tools/qtcreator/pip_types.py
|
||
\endcode
|
||
|
||
After that PIString, PIVector<T>, PIMap<K,V> and the other types from
|
||
the table above show their content in the Variables/Expressions views.
|
||
No changes to the GDB setup (`.gdbinit`, auto-load stub) are needed for
|
||
Qt Creator; those keep working for the command-line GDB.
|
||
|
||
\section verifying Verifying the installation
|
||
|
||
A check script builds a demo with all covered types and asserts the expected
|
||
GDB output:
|
||
|
||
\code{.bash}
|
||
tools/gdb/test/test_pp.sh build_linux
|
||
\endcode
|
||
|
||
\~russian
|
||
|
||
Вместе с PIP поставляется скрипт pretty-printer'ов для GDB, `tools/gdb/pip_pp.py`,
|
||
который выводит содержимое базовых типов вместо их внутренних полей:
|
||
|
||
| Тип | Пример вывода |
|
||
|-----|---------------|
|
||
| \a PIString | `"hello"` |
|
||
| \a PIByteArray | `{0x48, 0x65, 0x6c, 0x6c, 0x6f}` |
|
||
| \a PIChar | `'a'` или `U+043c` |
|
||
| \a PIVector<T> | `{1, 2, 3}` |
|
||
| \a PIDeque<T> | `{1, 2, 3}` |
|
||
| \a PIStringList | `{"one", "two"}` |
|
||
| \a PIMap<K,V> | `{"x": 1, "y": 2}` |
|
||
| \a PISet<T> | `{3, 5}` |
|
||
| \a PIPair<K,V> | `{"k", 7}` |
|
||
| \a PIVariant | `PIVariant(pivInt, 4 bytes)` |
|
||
| \a PINetworkAddress | `192.168.1.10:8080` |
|
||
|
||
Вложенные контейнеры выводятся рекурсивно, например `PIVector<PIString>`
|
||
выводится как `{"a", "bb"}`. Указатели на поддерживаемые типы показывают
|
||
адрес и содержимое: `(PIString *) 0x7fffffffdac0 "hello"`.
|
||
|
||
Принтеры только читают память и защищены от ошибок: при любом сбое GDB
|
||
возвращается к стандартному (сырому) выводу. Длинные контейнеры обрезаются,
|
||
по умолчанию выводится первые 32 элемента (хвост показывается как
|
||
`..., ... (N total)`); ограничение задаётся константой `_MAX_ELEMENTS`
|
||
в начале файла `pip_pp.py`.
|
||
|
||
Требование: исполняемый файл и библиотека PIP должны быть собраны с
|
||
отладочной информацией (`-g`).
|
||
|
||
\section loading Загрузка принтеров
|
||
|
||
Вручную (работает с любым деревом сборки):
|
||
|
||
\code{.gdb}
|
||
(gdb) source /path/to/pip/tools/gdb/pip_pp.py
|
||
\endcode
|
||
|
||
Выполнять после загрузки исполняемого файла (в сессии, запущенной как
|
||
`gdb ./program`, или после команды `file`).
|
||
|
||
Автоматически: CMake install ставит скрипт в
|
||
`<prefix>/share/pip/gdb/pip_pp.py` и auto-load заглушку
|
||
`<prefix>/lib/libpip.so-gdb.py` рядом с библиотекой. GDB выполняет заглушку
|
||
автоматически при загрузке libpip.so (см. руководство GDB, "Auto-loading
|
||
extensions"). Если библиотека установлена вне стандартного auto-load safe path
|
||
GDB, добавьте каталог один раз:
|
||
|
||
\code{.gdb}
|
||
(gdb) add-auto-load-safe-path /your/prefix/lib
|
||
\endcode
|
||
|
||
Или создайте <homedir>/.gdbinit файл и запишите туда строку
|
||
\code
|
||
add-auto-load-safe-path <root_dir>
|
||
\endcode
|
||
, где root_dir - это корневая директория, в рамках которой находятся библиотека и скрипт pip_pp.py.
|
||
|
||
Заглушка устанавливается только для shared-сборок; для статических сборок
|
||
используйте ручной `source`.
|
||
|
||
\section qtcreator Qt Creator
|
||
|
||
Окна Variables/Expressions в Qt Creator не используют pretty-printer'ы
|
||
GDB — у них собственный Python-дампер. PIP предоставляет модуль дампера
|
||
`tools/qtcreator/pip_types.py`, который покрывает те же типы, что и
|
||
`pip_pp.py`. Для включения:
|
||
|
||
1. Откройте настройки отладчика (Qt Creator -> Настройки -> Отладчик).
|
||
2. Переключитесь на вкладку «Переменные и выражения».
|
||
3. В поле "Extra Debugging Helper" укажите путь к файлу:
|
||
|
||
\code
|
||
/path/to/pip/tools/qtcreator/pip_types.py
|
||
\endcode
|
||
|
||
После этого PIString, PIVector<T>, PIMap<K,V> и другие типы из
|
||
таблицы выше будут показывать своё содержимое в окнах
|
||
«Переменные» и «Выражения». Изменения в настройках GDB (`.gdbinit`,
|
||
auto-load заглушка) для Qt Creator не нужны; они продолжают работать
|
||
для GDB из командной строки.
|
||
|
||
\section verifying Проверка установки
|
||
|
||
Скрипт проверки собирает демо со всеми поддерживаемыми типами и сверяет
|
||
ожидаемый вывод GDB:
|
||
|
||
\code{.bash}
|
||
tools/gdb/test/test_pp.sh build_linux
|
||
\endcode
|