【问题标题】:Why isn't Eclipse using GDB's pretty printing?为什么 Eclipse 不使用 GDB 的漂亮打印?
【发布时间】:2015-06-26 16:16:34
【问题描述】:

我在 Ubuntu 14.04 和 GDB 7.7.1 上使用 Eclipse 4.4.2。我正在尝试在 Eclipse 调试器中检查一些 C++ 标准库容器的内容。

到目前为止我已经尝试过:按照说明here,我运行了命令

svn co svn://gcc.gnu.org/svn/gcc/trunk/libstdc++-v3/python

将其复制到/home/myusername/prettyprint

然后我将此文本复制到我的 .gdbinit 中:

python
import sys
sys.path.insert(0, '/home/myusername/prettyprint/python')
from libstdcxx.v6.printers import register_libstdcxx_printers
register_libstdcxx_printers (None)
end

当我运行 gdb 时,我收到以下错误消息:

Traceback (most recent call last):
  File "<string>", line 4, in <module>
  File "/home/myusername/prettyprint/python/libstdcxx/v6/printers.py", line 1266, in register_libstdcxx_printers
    gdb.printing.register_pretty_printer(obj, libstdcxx_printer)
  File "/usr/myusername/gdb/python/gdb/printing.py", line 146, in register_pretty_printer
    printer.name)
RuntimeError: pretty-printer already registered: libstdc++-v6

我搜索了这方面的帮助,发现文件中的倒数第二行 (register_libstdcxx_printers (None)) 不是必需的,因此我将其删除。然后,当我运行gdb 并输入:

info pretty-print

我得到这个输出,说明后端安装正确:

global pretty-printers:
  .*
    bound
  libstdc++-v6
    __gnu_cxx::_Slist_iterator
    __gnu_cxx::__7::_Slist_iterator
    __gnu_cxx::__7::__normal_iterator
    __gnu_cxx::__7::slist
    __gnu_cxx::__normal_iterator
    __gnu_cxx::slist
    __gnu_debug::_Safe_iterator
    std::_Deque_const_iterator
    std::_Deque_iterator
    std::_List_const_iterator
    std::_List_iterator
    std::_Rb_tree_const_iterator
    std::_Rb_tree_iterator
    std::__7::_Deque_const_iterator
    std::__7::_Deque_iterator
    std::__7::_List_const_iterator
    std::__7::_List_iterator
    std::__7::_Rb_tree_const_iterator
---Type <return> to continue, or q <return> to quit---
    std::__7::_Rb_tree_iterator
    std::__7::__cxx11::basic_string
    std::__7::basic_string
    std::__7::bitset
    std::__7::deque
    std::__7::forward_list
    std::__7::list
    std::__7::map
    std::__7::multimap
    std::__7::multiset
    std::__7::priority_queue
    std::__7::queue
    std::__7::set
    std::__7::shared_ptr
    std::__7::stack
    std::__7::tuple
    std::__7::unique_ptr
    std::__7::unordered_map
    std::__7::unordered_multimap
    std::__7::unordered_multiset
    std::__7::unordered_set
    std::__7::vector
    [... many more lines of output omitted]

为了更好的衡量,我在.gdbinit 中添加了以下几行:

set print pretty on
set print object on
set print static-members on
set print vtbl on
set print demangle on
set demangle-style gnu-v3
set print sevenbit-strings off

于是我打开 Eclipse 开始调试我的应用程序,却发现丑陋的打印仍然有效:

如何解决这个问题以使用 GDB 的漂亮打印;是否安装了漂亮的打印?

【问题讨论】:

  • 注意:gdb -nxinfo pretty-print 不会产生任何输出。
  • 通常你的发行版应该正确安装所有东西。这就是该错误消息的真正含义——您的安装是多余的。 gdb -nx 不是一个充分的测试,因为漂亮的打印机是按需加载的;在这种情况下,当 libstdc++.so 由下级加载时。所以你必须用-nx试试。我不知道为什么 Eclipse 不工作,它可能应该工作。
  • @TomTromey 我应该注意我安装了 Eclipse 作为从 Eclipse Foundation 网站下载,而不是使用我系统的包管理器。你能解释一下我应该怎么做吗?用 gdb 加载 libstdc++.so 文件?
  • Eclipse 应该没关系。重要的是gdb。要尝试的一件事是使用 gdb -nx 调试一个普通的 C++ 程序。如果漂亮的打印在那里工作,那么这个错误就在 Eclipse 中。否则,它与您的 gdb(或 libstdc++ 或 ...)设置有关。
  • @TomTromey 我以前从未使用过 GDB,但我运行了一个基本会话,并且能够在 std::vector 初始化后打印它的内容:$3 = {&lt;std::__1::__vector_base&lt;int, std::__1::allocator&lt;int&gt; &gt;&gt; = {&lt;std::__1::__vector_base_common&lt;true&gt;&gt; = {&lt;No data fields&gt;}, __begin_ = 0x606010, __end_ = 0x6060e0, __end_cap_ = {&lt;std::__1::__libcpp_compressed_pair_imp&lt;int*, std::__1::allocator&lt;int&gt;, 2&gt;&gt; = {&lt;std::__1::allocator&lt;int&gt;&gt; = {&lt;No data fields&gt;}, __first_ = 0x6060e0}, &lt;No data fields&gt;}}, &lt;No data fields&gt;} 所以看起来问题出在 GDB 上。

标签: c++ eclipse debugging gdb


【解决方案1】:

您的屏幕截图中的值看起来像内存地址,这让我相信您正在尝试检查指向 STL 类型实例的 指针。 AFAIK,漂亮的打印机不会自动取消引用指针,但如果你 add a watch expression 尊重指针,就会漂亮地打印。

您使用的额外.gdbinit 行不应该是必需的;以下步骤是所有应该需要的(对于 Eclipse Mars.1):

  1. 下载漂亮的打印机:

    svn co svn://gcc.gnu.org/svn/gcc/trunk/libstdc++-v3/python
    
  2. 创建一个/home/&lt;user&gt;/.gdbinit 文件,内容如下:

    python
    import sys
    sys.path.insert(0, '/path/to/prettyprint/python')
    from libstdcxx.v6.printers import register_libstdcxx_printers
    end
    
  3. 在 Eclipse 的 GDB 设置中(Window->Preferences->C/C++->Debug->GDB),将 GDB 命令文件路径设置为刚刚创建的 .gdbinit 文件。

  4. 对于任何需要漂亮打印的现有调试配置(运行->调试配置),选择调试配置,然后在“调试器”选项卡上设置 GDB 命令文件路径。

您可以按如下方式验证 GDB 是否打印良好(完成上一过程的前两个步骤后):

  1. 将以下代码保存在名为test.cpp的文件中:

    #include <map>
    int main() {
        std::map<char, int> first;
        first['a'] = 10;
        first['b'] = 20;
    }
    
  2. 用 g++ 编译:

    $ g++ -g -o test test.cpp
    
  3. 运行 gdb:

    $ gdb test
    
  4. 设置断点:

    (gdb) b test.cpp:5
    Breakpoint 1 at 0x40093f: file src/test.cpp, line 5.
    
  5. 运行程序:

    (gdb) run
    Starting program: /path/to/test
    
  6. 当断点被击中时,将显示 gdb 提示符。使用以下命令打印地图:

    (gdb) p first
    

    如果一切正常,您应该会看到以下输出:

    $1 = std::map with 1 elements = {[97 'a'] = 10}
    

【讨论】:

  • 您忘记了 .gdbinit 文件中 end 之前的行 register_libstdcxx_printers (None)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多