Eclipse/CDT 漂亮的打印错误

Posted

技术标签:

【中文标题】Eclipse/CDT 漂亮的打印错误【英文标题】:Eclipse/CDT Pretty Print Errors 【发布时间】:2014-07-13 07:18:28 【问题描述】:

首先我要说的是,我在这里搜索了其他密切相关的问题,但并没有帮助解决我的问题。

设置:

Win7 笔记本电脑,SSH/X11 到 CentOS 6.4 最终运行 Eclipse Kepler SR2 w/CDT 8.3 GDB 7.2 无法访问 Internet 的托管公司服务器(所以没有 svn co...

我是使用 Eclipse/CDT 的新手,但熟悉 GDB。当我尝试调试使用 STL 的应用程序时,在第一次出现 STL 对象时,我收到以下错误。在有很多很多 STL 对象的程序上,我会遇到很多错误,以至于无法单步执行。我这里有一个用于说明目的的小示例程序。

这是我的示例程序:

#include <iostream>
using namespace std;

int main() 
    string sComplex;
    sComplex = "!!!Hello World!!!";
    cout << sComplex << endl; // prints !!!Hello World!!!
    //cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!!
    cout << "This is a new string that writes out a numeric..." << endl;
    int i = 1000;
    cout << "Value for integer 'i' is : '" << i << "'." << endl;
    cout << "  In HEX: '";
    cout << std::hex << std::showbase << i;
    cout << "'." <<endl;
    return 0;

以下是在第一行打印出来的错误(STL 字符串实例化):

Traceback(最近一次调用最后一次): 文件“/usr/lib64/../share/gdb/python/libstdcxx/v6/printers.py”,第 558 行,在 to_string return self.val['_M_dataplus']['_M_p'].lazy_string (length = len) RuntimeError: 无法访问地址 0xffffffffffffffe8 处的内存

Traceback(最近一次调用最后一次): 文件“/usr/lib64/../share/gdb/python/libstdcxx/v6/printers.py”,第 558 行,在 to_string return self.val['_M_dataplus']['_M_p'].lazy_string (length = len) RuntimeError: 无法访问地址 0xffffffffffffffe8 处的内存

Traceback(最近一次调用最后一次): 文件“/usr/lib64/../share/gdb/python/libstdcxx/v6/printers.py”,第 558 行,在 to_string return self.val['_M_dataplus']['_M_p'].lazy_string (length = len) RuntimeError: 无法访问地址 0xffffffffffffffe8 处的内存

首先,请注意这个对象有 3 个单独的错误。我已经验证安装了 python 漂亮的打印模块,并且我尝试了限制 to_string 长度的建议,但无济于事。如果我跳过字符串实例化,一切正常,我可以看到变量的简单字符串值。鼠标悬停看起来也不错。当我直接在命令行上使用 gdb 调试同一个应用程序时,我没有看到任何此类错误和变量值打印 pretty

(gdb) p sComplex
$1 = "!!!Hello World!!!"
(gdb) p sComplex.c_str()
$2 = 0x602028 "!!!Hello World!!!"

我已经用我的 .gdbinit 文件和 Eclipse 的 Window->Preferences->C/C++->Debug->GDB 设置尝试了各种建议,甚至禁用了漂亮的打印,但它仍然会发生。我不知道接下来要尝试什么。

【问题讨论】:

python 文件与您的 C++ 程序或 Eclipse 环境有什么关系?这里出了点问题 @jasal,GDB 7.0 包括通过 python 插件脚本对 C++ STL 结构的“漂亮打印”支持:[sourceware.org/gdb/wiki/STLSupport](STLSupport)。这在 GDB 中对我来说很好,但在我运行 Eclipse 时会出现问题。 【参考方案1】:

我向 Eclipse (Pretty Print Errors Render Eclipse Debugging Impossible) 提交了一个票证,Marc Dumais 的回答指出此错误是 GDB 缺陷的结果。在修补 GDB 之前,我发现在 Eclipse 中仍然使用漂亮打印(根据 Marc 的建议)解决此错误的唯一方法是隐藏任何活动的变量窗口/选项卡。这可以防止 Eclipse 向 GDB 询问可能尚未初始化的变量的初始值。

在“调试”透视图中将“变量”选项卡作为背景即可解决问题。此解决方案可能依赖于代码,因为具有许多未初始化变量的代码可能仍然难以调试。

【讨论】:

【参考方案2】:

我最终决定重新审视这个问题,并最终通过遵循类似于this one 的解决方案以及对我的自定义printers.py 进行额外编辑来解决它。希望这可以帮助其他遇到此问题的人。

    结帐漂亮的打印机 (svn co svn://gcc.gnu.org/svn/gcc/trunk/libstdc++-v3/python) 到 $HOME/gdb/gdb_printers/。 如果您无法结帐(如果您的组织像我一样阻止外部 svn),请查看是否可以从系统位置复制它(例如 /usr/share/gdb/)。 完成后,您应该有这样的目录结构:

这个结构必须是精确的,否则它不会使用 /v6/ 中的 printers.py。

    编辑printers.py,特别是StdStringPrinter::to_string,如下(添加try/except/else):

    def to_string(self):
        # Make sure &string works, too.
        type = self.val.type
        if type.code == gdb.TYPE_CODE_REF:
            type = type.target ()
    
        # Calculate the length of the string so that to_string returns
        # the string according to length, not according to first null
        # encountered.
        # I wrapped this section in a try/except/else block so that uninitialized
        # strings don't cause massive RuntimeError exception reporting during debugging
        # with or without pretty printers enabled. -jkw
        try:
             ptr = self.val ['_M_dataplus']['_M_p']
             realtype = type.unqualified ().strip_typedefs ()
             reptype = gdb.lookup_type (str (realtype) + '::_Rep').pointer ()
             header = ptr.cast(reptype) - 1
             len = header.dereference ()['_M_length']
        except RuntimeError:
             #print 'Caught exception'
             return ''
        else:
             return self.val['_M_dataplus']['_M_p'].lazy_string (length = len)
    

    创建/编辑$HOME/gdb/.gdbinit 文件并将以下内容放入其中。 请注意,路径必须与上述图像/树视图中的“python”目录的路径匹配。

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

    在 Eclipse 中,在 Window -&gt; preferences -&gt; C/C++ -&gt; Debug -&gt; GDB 下,将路径设置为 gdb 和您的 .gdbinit 文件。您可能还需要在您想要使用您的打印机的任何现有调试配置上进行设置。py。

    GDB debugger: /usr/bin/gdb
    GDB command file: /home/(user_id)/gdb/.gdbinit
    

从那里开始,调试功能就像您认为的那样。

【讨论】:

以上是关于Eclipse/CDT 漂亮的打印错误的主要内容,如果未能解决你的问题,请参考以下文章

Eclipse CDT 的额外重构

Eclipse CDT:如何在 C 源代码上使用 GCC C++ 编译器?

Eclipse CDT 显示语义错误,但编译正常

带有 MinGW GCC 的 Eclipse CDT 生成错误 127

使用 Profiling Tools 的 Function Callgraph 选项时出现 Eclipse CDT 错误

eclipse cdt 中的‘字符串’没有命名类型错误”