Почему в GDB ptype / o отсутствуют некоторые поля на некоторых платформах? - PullRequest
0 голосов
/ 23 апреля 2020

( Почему при отладке некоторые поля "отсутствуют"? (c#) выглядит аналогично, но это не так)

Контекст

У меня есть переменная Nlohmann JSON simple_json и отлаживаемая программа, включены символы отладки. Я хочу исследовать память и наблюдать смещения полей.

Я могу получить адрес в GDB:

(gdb) p &(*simple_json.m_value.object)
(nlohmann::basic_json<std::map, <lots of stuff removed>, nlohmann::adl_serializer>::object_t *) 0x174d20

Точно так же, у меня могут быть другие адреса:

(gdb) p &(*simple_json.m_value.object)._M_t
(gdb) p &(*simple_json.m_value.object)._M_t._M_impl
# both gives same value. This is due to how C++ STL are made.
# perfectly normal
# (obviously not the same type, all GDB outputs truncated for sake of readability)
(... redacted ...) 0x174d20

(gdb) p &(*simple_json.m_value.object)._M_t._M_impl._M_header
(std::_Rb_tree_node_base *) 0x174d28

# left node
(gdb) p &(*simple_json.m_value.object)._M_t._M_impl._M_header._M_left
(std::_Rb_tree_node_base::_Base_ptr *) 0x174d38

Проблема

Итак, на моей платформе есть разница 0x8 (8) между simple_json.m_value.object._M_t._M_impl и simple_json.m_value.object)._M_t._M_impl._M_header Fine.

Но когда я прошу GDB напечатать структуры для _M_impl нет никакой подсказки, что:

  • имеет поле _M_header
  • _M_header поле имеет известное смещение

См. (Победа 64b):

(gdb) ptype /o (*simple_json.m_value.object)._M_t._M_impl
/* offset    |  size */  type = struct std::_Rb_tree< ... redacted...> {

                           /* total size (bytes):   48 */
                         }

Однако ptype, похоже, работает на другой платформе (здесь raspi 3+ 32b; точно такой же код + параметры компиляции):

(gdb) ptype /o (*simple_json.m_value.object)._M_t._M_impl
/* offset    |  size */  type = struct std::_Rb_tree< ... redacted ... > {
                         public:
/*    0      |     1 */    _Key_compare _M_key_compare;
/* XXX  3-byte hole */
/*    4      |    16 */    struct std::_Rb_tree_node_base {
/*    4      |     4 */        std::_Rb_tree_color _M_color;
/*    8      |     4 */        _Base_ptr _M_parent;
/*   12      |     4 */        _Base_ptr _M_left;
/*   16      |     4 */        _Base_ptr _M_right;

                               /* total size (bytes):   16 */
                           } _M_header;
/*   20      |     4 */    size_type _M_node_count;

                           /* total size (bytes):   24 */
                         }

Не нашел подсказки по проблемам GDB база данных: https://sourceware.org/bugzilla/buglist.cgi?quicksearch=ptype


Вопрос

  • Почему GDB не может отображать поля _M_impl на некоторых платформах?
  • Могу ли я что-нибудь сделать для одинакового поведения GDB на разных платформах?

С такими же параметрами оптимизации (здесь -o0 mea я думал, что разные платформы будут давать одинаковые результаты.

Чего мне не хватает? Это как-то связано с 1800+ строками #if ... #define из https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json.hpp?

Я знаю, что есть python GDB принтер pahole, который мог бы дать мне больше информации, но это не главное для моего вопроса (я хочу знать «почему?», а не «как я могу жить без?»)


MCVE / Версии инструментов

Набор инструментов для компиляции:

  • Выигрыш: GNAT Community 2019 (20190517-83)
  • Распи: GNAT 6.3.0

GDB версии:

  • победа: GNU gdb (GDB) 8.3 for GNAT Community 2019 [rev=gdb-8.3-ref-194-g3fc1095]
  • распи: GNU gdb (GDB) 8.3.1

MCVE (main. cpp, используется json .h от nlohmann json repo):

#include "json.hpp"
#include <iostream>
using json = nlohmann::json;
int main() {
  json simple_json;
  simple_json["some_key"] = "any_value_you_like";
  std::cout << " a console print" << std::endl; // <-- breakpoint here
  return 0;
}

Параметры компиляции / ссылки (файл проекта GPR):

project my_project is

    for Source_Dirs use ("src", "include");
    for Object_Dir  use "obj";
    for Exec_Dir    use "exe";
    for Main        use ("main.cpp");
    for Languages   use ("C++");

    package Naming is
        for Spec_Suffix ("C++") use ".hpp";
        for Body_Suffix ("C++") use ".cpp";
    end Naming;

    package Compiler is
        -- no optims for ease of debug breakpoints; keep debug symbols
        for Switches ("C++") use ("-O0", "-Wall", "-Woverloaded-virtual", "-g", "-std=c++11");
    end Compiler;

    package Linker is
        for Switches ("C++") use ("-g"); -- keep debug symbols !
    end Linker;

end my_project;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...