调用成员方法时,此指针会丢失

时间:2012-09-10 09:45:10

标签: c++ g++ x86-64

在Fedora 17 x86_64计算机上使用64位g ++ 4.7.0编译我的程序时遇到了一个奇怪的问题(同样的程序在32位Fedora上运行良好)。

程序太复杂了,我无法找到一种简单的方法来生成一个小代码示例。但是从下面的gdb记录中,你可以看到问题。

Program received signal SIGSEGV, Segmentation fault.
0x000000000042a4b0 in boost::shared_ptr<cppPNML::details::ddObj>::operator!(this=0x100000007)
    at /usr/include/boost/smart_ptr/detail/operator_bool.hpp:55
55          return px == 0;
Missing separate debuginfos, use: debuginfo-install gnome-keyring-3.4.1-3.fc17.x86_64
(gdb) bt
#0  0x000000000042a4b0 in boost::shared_ptr<cppPNML::details::ddObj>::operator! (this=0x100000007)
    at /usr/include/boost/smart_ptr/detail/operator_bool.hpp:55
#1  0x00000000004202a5 in cppPNML::pnNode::getBBox (this=0xffffffff) at cpp_pnml.cpp:131
#2  0x000000000040eca4 in draw_page (g=..., painter=...) at pnml2pdf.cpp:178
#3  0x000000000040e3b9 in main (argc=2, argv=0x7fffffffe188) at pnml2pdf.cpp:106
(gdb) up
#1  0x00000000004202a5 in cppPNML::pnNode::getBBox (this=0xffffffff) at cpp_pnml.cpp:131
131   if(!p_) return pair<double, double>(0,0);
(gdb) up
#2  0x000000000040eca4 in draw_page (g=..., painter=...) at pnml2pdf.cpp:178
178     boost::tie(w, h) = node.getBBox();
(gdb) p node
$1 = {<cppPNML::pnObj> = {_vptr.pnObj = 0x79a490, p_ = {px = 0x7c40a0, pn = {pi_ = 0x7c4170}}}, <No data fields>}
(gdb) l
173   QRectF bound(0,0,0,0);
174   
175   // nodes
176   for(pnNode node = g.front<pnNode>(); node.valid(); node = node.next()) {
177     double h, w, x, y, wa, ha, xa, ya, angle;
178     boost::tie(w, h) = node.getBBox();
179     angle = atan2(h, w);
180     boost::tie(x, y) = node.getPosition();
181     wa = 0; ha = 0; xa = 0; ya = 0;
182     
(gdb)

正在调试的程序是一个图形打印程序(pnml2pdf),它使用QT4将图形绘制为pdf。 对象节点属于类pnNode,它由我自己的图形数据结构库(非常复杂,https://github.com/wsong83/cppPNML)定义。 显示智能指针未初始化的SEG错误。 通过后跟踪,您可以看到node.getBBox()的this指针无效。 但是,从上一级打印节点显示节点实际上是正常的。

我在这里完全糊涂了。

任何人都有任何线索或需要更多代码段?提前谢谢!

更新: 感谢@atzz的建议,我现在肯定在成员方法getBBox()中计算这个指针产生了一个错误的地址。问题不是由任何源代码错误引起的(直接链接目标文件将消除段错误),而是由64位静态库生成命令“ar”引起(因为pnNode的定义是在静态库中定义而不是对象文件)。现在看来静态库是错误的并导致错误的计算。

仍在挖掘......如果有人仍有兴趣知道,将更新结果。

1 个答案:

答案 0 :(得分:0)

  1. 这是优化版本还是调试版本?在我看来它应该在第176行而不是第178行失败。

  2. 你确定循环是对的吗?看起来你要走到最后。我怀疑你node.valid()的实现要么做得不对,要么对循环测试是错误的。

  3. 0xffffffff看起来像std::iterator end()值,因此我认为您需要针对该值测试循环,或确保pnObj::valid() const { return p_ != NULL && p_ != 0xffffffff; }

    您实施next()的方式看起来也不错。创建一个迭代器,搜索字符串ID,然后在迭代器上调用next()