-1

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)

デバッグ中のプログラムは、QT4 を使用してグラフを pdf に描画するグラフィック印刷プログラム (pnml2pdf) です。オブジェクト ノードは、私自身のグラフィック データ構造体ライブラリ (非常に複雑なhttps://github.com/wsong83/cppPNML )で定義されているクラス pnNode に属しています。スマート ポインターが初期化されていない場合、SEG エラーが表示されます。バック トレースを介して、node.getBBox() の this ポインターが無効であることがわかります。ただし、1 レベル上のノードからノードを印刷すると、ノードが実際には問題ないことが示されます。

私はここで完全に混乱しています。

誰か手がかりを持っているか、それ以上のコード セグメントが必要ですか? 前もって感謝します!

更新: @atzz からのアドバイスのおかげで、メンバー メソッド getBBox() でのこのポインターの計算が間違ったアドレスを生成したことがわかりました。この問題は、ソース コードのエラー (オブジェクト ファイルを直接リンクするとセグメント フォールトが解消されます) が原因ではなく、64 ビットの静的ライブラリ生成コマンド「ar」が原因です (pnNode の定義は、静的ライブラリではなく静的ライブラリで定義されているため)。オブジェクトファイル)。静的ライブラリが間違っているようで、この計算が間違っているようです。

まだ掘り下げ中... 誰かがまだ知りたいと思っている場合は、結果を更新します。

4

1 に答える 1

0
  1. これは最適化されたビルドですか、それともデバッグ ビルドですか? 178行目ではなく176行目で失敗するはずです。

  2. ループは正しいですか?あなたは終わりを越えているようです。あなたの実装はnode.valid()正しいことをしていないか、ループテストにとって間違っていると思います。

値は値のように0xffffffff見えるstd::iterator end()ので、それに対してループをテストするか、pnObj::valid() const { return p_ != NULL && p_ != 0xffffffff; }

また、実装方法next()が間違っているように見えます。イテレータを作成し、文字列 ID を検索してからイテレータを呼び出しnext()ますか?

于 2012-09-10T10:32:37.420 に答える