11

私はこのスレッドを見てきました。私の場合は少し異なり、"this"ポインターがどのように破損しているのかを理解するのに苦労しています。

QTreeView私は自分のモデルでQt 4.6.2 フレームワークを使用しています。私が取得したバックトレース (長さ 86 フレーム、再帰が多いため、すべてを貼り付けていないのはこのためです。このペーストビンにはコードのみが含まれています。

最終的に QBasicAtomicInt::deref の一部のアセンブラで segfault が発生しますが、次の 3 つのフレームで証明されているように、さらにダウンしたことは明らかです。

#15 0x01420fd3 in QFrame::event (this=0x942bba0, e=0xbf8eb624) at widgets/qframe.cpp:557
#16 0x014bb382 in QAbstractScrollArea::viewportEvent (this=0x4, e=0x93f9240) at widgets/qabstractscrollarea.cpp:1036
#17 0x0156fbd7 in QAbstractItemView::viewportEvent (this=0x942bba0, event=0xbf8eb624) at itemviews/qabstractitemview.cpp:1610

フレーム 17 では、thisです0x942bb0。フレーム 16 ではthis、同じメソッドの祖先の実装を呼び出しているフレーム 17 と同じである必要があります。ただしthis、0x4 になります。

興味深いことに、フレーム 15 では (フレーム 16 で同じ関数の祖先の実装が呼び出されています)、「this」ポインターが に復元され0x942bba0ます。

完全なバックトレースのペーストビンを見ると、「値が最適化されていない」ことがわかる場合があります。最適化をオンにしてアプリケーションをコンパイルしました。私は今gccを設定して-g3 -O0いるので、次回それが起こったときはもっと何かがあるかもしれません. しかし、もちろん、今はクラッシュさせることはできません。これを発生させるのはかなり難しいバグです (ただし、修正することは非常に重要です)。

最適化を考えると、それはthis pointer=0x4異常ですか、それとも間違いですか? 奇妙なのは、これらの viewportEvent フレームのいずれにも実際のコードがないことです。これらのフレームは単にイベントのタイプを切り替え、switch ステートメントを通過し、先祖の実装を返します。

Valgrind ではまだクラッシュしていませんが、Valgrind で問題が発生しているようには見えません。

誰もこの動作を見たことがありますか? 何が原因でしょうか?

4

1 に答える 1

8

最適化されたビルドをデバッグするときにこの種のことを見たことがありますが、実際のバグが何であるかを示すものではありませんでした。

最初にローカル変数について考える方が簡単です。最適化されていないビルドでは、すべてがメモリ内の指定された場所にあり、すべてのコード行の後に格納する必要があります。これは、デバッガーがそれを見つけることができるようにするためです。最適化されたビルドでは、値はメモリに書き込まれずにレジスタに存在できます。これは、最適化されたビルドのパフォーマンス向上の主要な部分です。デバッガーはこれを理解せず、常にメモリを参照するため、間違った値が表示されることがよくあります。

パラメータでも同じことが起こります。オプティマイザーがパラメーターをレジスターに渡すことを決定した場合、デバッガーは引き続きスタックフレームを調べます。より具体的には、呼び出し規約の規則に従ってパラメーターが配置される場所。

スタックの次のフレームに値が適切に復元されているという事実は、生成された命令が this パラメーターを正しく処理していることを示していますが、デバッガーはそれを探す場所を認識していません。

于 2011-08-30T07:47:57.873 に答える