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

Изучите boost shared_ptr с помощью gdb

Ниже приведен мой исходный код:

#include <iostream>
#include <boost/shared_ptr.hpp>

class MyClass
{
    public:
        MyClass()
        {
            i=10;
        }
    private:
        int i;
};


int main(int argc, const char *argv[])
{
    boost::shared_ptr <MyClass> obj(new MyClass());
    return 0;
}

Я хочу изучить obj в gdb и посмотреть значение переменной-члена i.

Это то, что я получаю при обычной печати:

29          boost::shared_ptr <MyClass> obj(new MyClass());
(gdb) n
30          return 0;
(gdb) p obj
$1 = {px = 0x602010, pn = {pi_ = 0x602030}}

Я попробовал наконечник, упомянутый в этой ссылке, но не работает.

(gdb) call (obj.get())->print()
Cannot evaluate function -- may be inlined

Есть ли другой способ? Версия gdb - 7.0.1.

4b9b3361

Ответ 1

Получил.!

(gdb) set print pretty
(gdb) p obj
$5 = {
  px = 0x602010,
  pn = {
    pi_ = 0x602030
  }
}
(gdb) p obj.px
$6 = (MyClass *) 0x602010



(gdb) p *(obj.px)
$7 = {
  i = 10
}

Ответ 2

Попробуйте следующее:

print (* obj.px).i

полный код приведен ниже:

 (gdb) list 1,23
1       #include <iostream>
2       #include <boost/shared_ptr.hpp>
3       #include <string>
4
5       class MyClass
6       {
7           public:
8               MyClass()
9                   : name("Testing")
10              {
11                  i=10;
12              }
13          private:
14              int i;
15              std::string name;
16      };
17
18
19      int main(int argc, const char *argv[])
20      {
21          boost::shared_ptr <MyClass> obj(new MyClass());
22          return 0;
23      }
(gdb) p obj
$9 = {px = 0x602010, pn = {pi_ = 0x602060}}
(gdb) p (*obj.px).i
$10 = 10
(gdb) p (*obj.px).name
$11 = {static npos = 18446744073709551615,
  _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>},
    _M_p = 0x602048 "Testing"}}

Ответ 3

Это будет сложно ответить. GDB 7.x добавила поддержку сценариев Python. В Интернете есть некоторые ресурсы. Вместо того, чтобы делать плохую попытку посоветовать что-то, у меня нет первого опыта, я отсылаю вас к предыдущему сообщению:

С++ GDB Python Pretty Printing Tutorial?

Ответ 4

При компиляции используйте параметр -ggdb и посмотрите, работает ли это

http://sourceware.org/gdb/onlinedocs/gdb/Inline-Functions.html

Inlining - это оптимизация, которая вставляет копию тела функции непосредственно на каждый сайт вызова вместо перехода к общей процедуре. gdb отображает встроенные функции так же, как не-встроенные функции. Они появляются в обратном направлении. Вы можете просматривать их аргументы и локальные переменные, вступать в них с шагом, пропускать их со следующего и выходить из них с завершением. Вы можете проверить, была ли функция встроена с помощью команды информационного фрейма.

Чтобы gdb поддерживал встроенные функции, компилятор должен записывать информацию о inlining в отладочной информации - gcc, используя формат dwarf 2, делает это, а также некоторые другие компиляторы. gdb поддерживает только встроенные функции при использовании карлика 2. Версии gcc до 4.1 не испускают два обязательных атрибута ('DW_AT_call_file и' DW_AT_call_line); gdb не отображает встроенные вызовы функций с более ранними версиями gcc. Вместо этого он отображает аргументы и локальные переменные встроенных функций как локальные переменные в вызывающем.

Тело встроенной функции непосредственно включается на свой сайт вызова; в отличие от не-встроенной функции, для вызова нет инструкций. gdb все еще делает вид, что сайт вызова и начало встроенной функции - разные инструкции. Переход на сайт вызова показывает сайт вызова, а затем повторное нажатие показывает первую строку встроенной функции, даже если никаких дополнительных инструкций не выполняется.

Это значительно облегчает отладку на уровне исходного кода; вы можете видеть как контекст вызова, так и эффект вызова. Только шаг за шагом одной командой с помощью stepi или nexti не делает этого; отдельные шаги инструкции всегда показывают встроенное тело.

Есть несколько способов, что gdb не претендует на то, что вызовы встроенных функций совпадают с обычными вызовами:

Установка точек останова на сайте вызова встроенной функции может не работать, поскольку сайт вызова не содержит никакого кода. gdb может неправильно переместить точку останова на следующую строку закрывающей функции после вызова. Это ограничение будет удалено в будущей версии gdb; до тех пор, установите контрольную точку на более ранней строке или внутри встроенной функции. gdb не может найти возвращаемое значение встроенных вызовов после использования команды завершения. Это ограничение генерируемой компилятором отладочной информации; после завершения вы можете перейти к следующей строке и распечатать переменную, в которой ваша программа сохранила возвращаемое значение.