【问题标题】:Examine boost shared_ptr with gdb使用 gdb 检查 boost shared_ptr
【发布时间】:2013-07-22 05:09:00
【问题描述】:

以下是我的源代码:

#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;
}

我想查看gdb中的obj,查看成员变量i的值。

这是我用普通打印得到的:

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

我尝试了this link 中提到的技巧,但不起作用。

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

还有其他方法吗? gdb 版本是 7.0.1。

【问题讨论】:

  • 另一个好老朋友是plain printf :)
  • @Anand Rathi...,是的,但我只是想知道 gdb 是否可以做到这一点。

标签: c++ boost gdb shared-ptr


【解决方案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
}

【讨论】:

  • 这是我一整天看到的最有用的东西!!!万分感谢。我没有意识到我可以以这种方式取消引用指针。 :-)
  • 这对我不起作用。 “p obj”给出$2 = std::shared_ptr (count 2, weak 1) 0x639268,“p obj.px”给出There is no member or method named px。我也试过“p *obj”,但不高兴:Could not find operator*.
【解决方案2】:

试试这个:

打印 (*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 脚本支持。网上有一些资源。与其对我没有第一次经验的事情提出建议,不如向您推荐过去的帖子:

    C++ GDB Python Pretty Printing Tutorial?

    【讨论】:

      【解决方案4】:

      当你编译时使用 -ggdb 选项看看是否有效

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

      内联是一种优化,它直接在每个调用点插入函数体的副本,而不是跳转到共享例程。 gdb 像非内联函数一样显示内联函数。它们出现在回溯中。您可以查看它们的参数和局部变量,使用 step 进入它们,使用 next 跳过它们,并使用 finish 退出它们。您可以使用 info frame 命令检查函数是否被内联。

      为了让 gdb 支持内联函数,编译器必须在调试信息中记录有关内联的信息——使用 dwarf 2 格式的 gcc 会这样做,其他几个编译器也这样做。 gdb 仅在使用 dwarf 2 时支持内联函数。4.1 之前的 gcc 版本不会发出两个必需的属性(“DW_AT_call_file”和“DW_AT_call_line”); gdb 不显示早期版本的 gcc 的内联函数调用。而是将内联函数的参数和局部变量显示为调用者中的局部变量。

      内联函数的主体直接包含在其调用点;与非内联函数不同,没有专门用于调用的指令。 gdb 仍然假装调用站点和内联函数的开始是不同的指令。单步执行调用站点会显示调用站点,然后再次单步执行会显示内联函数的第一行,即使没有执行其他指令。

      这使得源代码级调试更加清晰;您可以看到调用的上下文以及调用的效果。仅使用 stepi 或 nexti 单步执行一条指令不会执行此操作;单个指令步骤始终显示内联正文。

      gdb 有一些方法不会假装内联函数调用与普通调用相同:

      在内联函数的调用点设置断点可能不起作用,因为调用点不包含任何代码。 gdb 可能会在调用之后错误地将断点移动到封闭函数的下一行。此限制将在 gdb 的未来版本中删除;在此之前,请在较早的行或内联函数内设置断点。 使用完成命令后,gdb 无法找到内联调用的返回值。这是编译器生成的调试信息的限制;完成后,您可以跳到下一行并打印程序存储返回值的变量。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-04
        • 2022-01-12
        • 1970-01-01
        相关资源
        最近更新 更多