使用gdb调试boost shared_ptr

20

以下是我的源代码:

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

我尝试了这个链接中提到的提示,但不起作用。

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

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


另一个好老朋友是简单的printf :) - Anand Rathi
1
@ Anand Rathi...,是的,但我只是想知道是否可以使用gdb实现。 - m.divya.mohan
4个回答

30

明白了!

(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
}

3
今天以来我看到的最有用的东西!!!非常感谢。我没想到可以这样取消指针引用。 :-) - kmort
3
这对我没用。"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*. - Chris Dodd

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"}}

0

这将是一个难以回答的问题。GDB 7.x 添加了 Python 脚本支持。网络上有一些资源可用。与其试图就我没有第一手体验的事情提供建议,不如提到过去的帖子:

C++ GDB Python Pretty Printing Tutorial?


0

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

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

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

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

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

这使得源代码级别的调试更加清晰;您可以看到调用的上下文以及调用的效果。使用stepi或nexti单步执行一条指令并不能做到这一点;单个指令步骤总是显示内联体。

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

在内联函数调用的调用点设置断点可能无法正常工作,因为调用点不包含任何代码。 gdb可能会错误地将断点移动到调用后封闭函数的下一行。这个限制将在未来的gdb版本中被删除;在那之前,请在较早的行或内联函数内设置断点。

在使用finish命令后,gdb无法定位内联调用的返回值。这是编译器生成的调试信息的限制;在完成后,您可以跨越到下一行并打印程序存储返回值的变量。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接