在 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 的定义是在静态库中定义的,而不是目标文件)。现在看来静态库是错误的,导致这个计算错误。
仍在挖掘...如果有人仍然有兴趣知道,将更新结果。