0

new最近、デフォルトをオーバーライドしなければならなかったコードでクラッシュが発生し始めましたdelete。完全にはわかりませんが、最近のソフトウェア更新の後である可能性があります。

Osx 10.8.2 ビルド 12C54 と次の gcc を実行しています。

i686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1

これが私のクラッシュのスタックトレースです。

(gdb) bt
#0  0x00007fff8f2a4212 in __pthread_kill ()
#1  0x00007fff8fdecaf4 in pthread_kill ()
#2  0x00007fff8fe30dce in abort ()
#3  0x00007fff8fe04959 in free ()
#4  0x00000001009cd947 in foundation::aligned_free ()
#5  0x00000001009e5322 in (anonymous namespace)::delete_impl ()
#6  0x00000001009e53e8 in operator delete[] ()
#7  0x00007fff87316ecc in TPropertyStream::SetLength ()
#8  0x00007fff87286099 in TPropertyStream::WriteData ()
#9  0x00007fff87286037 in TPropertyStream::Write ()
#10 0x00007fff87285ce7 in IAStoreStream::MaybeFlushBuffer ()
#11 0x00007fff87285641 in BuddyStorage::Commit ()
#12 0x00007fff87316c4c in TPropertyInfo::FlushChanges ()
#13 0x00007fff873169af in TPropertyInfo::FlushChanges ()
#14 0x00007fff8729ac47 in THFSPlusPropertyStore::FlushChanges ()
#15 0x00007fff872dc5e4 in TFSVolumeInfo::FlushVolumes ()
#16 0x00007fff872b087a in TNode::HandleFlushVolumes ()
#17 0x00007fff872684d3 in TNode::HandleNodeRequest ()
#18 0x00007fff872db4e7 in __block_global_1 ()
#19 0x00007fff87268040 in ExceptionSafeBlock ()
#20 0x00007fff87267fe1 in __PostNodeTaskRequest_block_invoke_0 ()
#21 0x00007fff8e074f01 in _dispatch_call_block_and_release ()
#22 0x00007fff8e0710b6 in _dispatch_client_callout ()
#23 0x00007fff8e07247f in _dispatch_queue_drain ()
#24 0x00007fff8e0722f1 in _dispatch_queue_invoke ()
#25 0x00007fff8e0721c3 in _dispatch_worker_thread2 ()
#26 0x00007fff8fdedcab in _pthread_wqthread ()
#27 0x00007fff8fdd8171 in start_wqthread ()

誰かが同様の問題を経験しましたか?

4

2 に答える 2

1

いずれにせよ、私たちの演算子を使用するべきではありません。理想的には、オーバーロードされた new と delete は、Windows の場合のように外部に隠されます (そのプラットフォームでは共有ライブラリ シンボルがデフォルトで隠されているため)。

通常、Unix の共有ライブラリの可視性は、C++ の外部リンケージに対応します。つまり、項目に C++ 言語の外部リンケージがある場合、その項目は共有ライブラリで外部から参照できます。GCC の可視性属性は、リンケージの変更として文書化されています。(または、以前はそうでしたが、今は見られません...)

さらに、ロード時リンクは、C++ の変換フェーズのフェーズ 9 の一部と見なすことができるため、UNIX プラットフォームでの共有オブジェクトと dylib のロード時リンクは、通常、動的リンクではなく静的リンクのように動作します。つまり、operator new読み込み時にリンクされる翻訳単位で置換すると、読み込み時リンカーは、静的にリンクされた翻訳単位の 1 つを置換した場合と同様に、すべての静的および読み込み時にリンクされた翻訳単位に対してこれを解決しますoperator new

別の翻訳単位で割り当てられたある翻訳単位で割り当てられたメモリを削除することは、完全に合法であり、C++ で明確に定義されています。デフォルトでは、読み込み時のリンクはこの点で静的リンクと同じであるため、読み込み時にリンクされた翻訳単位間でもこれを行うコードがたくさんあります。繰り返しになりますが、ロード時のリンクがフェーズ 9 の一部であり、したがって C++ 仕様に拘束されることが適切に理解されている限り、これは合法的で明確に定義されています。

もちろん、これはdlopen()、フェーズ 9 が終了してプログラムが実行を開始した後に発生するような、ルーチンを使用した完全に動的なリンクには適用されません。このようなプログラムの動作は実装定義 (または C++03 では未定義) であるため、ある TU で割り当てられたリソースを別の TU で割り当て解除できるという要件に拘束されません。


問題は、Windows がこのように動作しないことです。Windows の読み込み時のリンクは、動的リンクのように動作するようであり、シンボルまたは型がエクスポートされるかどうかは、C++ の外部可視性とは関係ありません。実際、私が知る限り::operator new、Windows dll でエクスポートすることさえできません。

Windows の読み込み時のリンクが本当に準拠しているとは確信していませんが、多くのコードがそれに対処する必要があります。いずれかの環境でのみ実行する必要があるコードの場合は問題ありませんが、Windows と他の実装の両方で実行する必要があるコードの場合は、より注意が必要です。最も一般的な方法は、単にoperator neworをオーバーロードしないことoperator deleteです。割り当て関数と割り当て解除関数を別の名前で、おそらく C++ Allocator クラスとして記述できます。独自のユーザー定義型のみを処理する必要がある場合の別のオプションは、operator new/deleteそれらの型を処理するメンバーを定義することです。

于 2012-12-06T22:49:02.487 に答える
1

Jon は親切にも私たちの問題を SO に投稿してくれました。私は問題のコードの作成者です。何年も問題なく Mac OS X 用のコードを出荷してきました。また、Windows (32 ビットおよび 64 ビット) と多くの種類の Linux も出荷しています。Mac OS X でトラブルが発生したのはごく最近のことです。

基本的に、私たちのアプリは、いくつかの共有ライブラリ (Mac OS X では .dylib) を使用するいくつかのバイナリで構成されています。newおよびのすべてのバリアントはdelete、これらの共有ライブラリのいずれかにオーバーロードされています。それらはエクスポートされ、他の共有ライブラリとバイナリによって使用されることは想定されておらず、実際、Windows にはありません。参考までに、オーバーロードされた演算子はhereです。

何が起こっているのか正確にはわかりませんが、上記のコールスタックは、一部の Mac OS X コードが独自のdelete演算子を使用してメモリを解放していることを示しているようnewです。別のメモリ サブシステムに完全に割り当てられました。

いずれにせよ、私たちの演算子を使用するべきではありません。理想的には、オーバーロードnewdeleteれ、Windows の場合のように外部に隠されます (そのプラットフォームでは共有ライブラリ シンボルがデフォルトで隠されているため)。

コードは、gcc 4.2.1 (686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1 (Apple Inc. ビルド 5658 に基づく) (LLVM ビルド 2336.11.00) に基づく) を使用して、Mac OS X 10.8.2 でビルドされました。 )。とりわけ、Qt 4.8.2 (執筆時点での最新の安定版) のビルド済みバイナリを使用しています。最近、Mac OS X で新しいバージョンの Qt に切り替えましたが、それが問題に関連している可能性はありますか? ビルド済みの Qt バイナリが私たちのコードと互換性がない可能性はありますか? (Qt に対して動的にリンクしているので、問題にはなりません。)

会話を始めるのに十分な詳細であることを願っています.

フランツ

于 2012-12-06T21:25:16.493 に答える