3

C++ プログラムを FreeBSD から RHEL に移植しています。プログラムをテストしたところ、boost::shared_ptr::~shared_ptr() を呼び出すとプロセスがハングすることがわかりました。

gdb を使用してハングしているプロセスをアタッチしました。スタック トレースは次のとおりです。

(gdb) bt
#0  0x00e01430 in __kernel_vsyscall ()
#1  0x00bd8d96 in __pause_nocancel () from /lib/libpthread.so.0
#2  0x00bd30b2 in __pthread_mutex_lock_full () from /lib/libpthread.so.0
#3  0x04a60a26 in pthread_mutex_lock () from /lib/libc.so.6
#4  0x08069b61 in boost::detail::lightweight_mutex::scoped_lock::scoped_lock(boost::detail::lightweight_mutex&) ()
#5  0x080699d3 in boost::detail::sp_counted_base::release() ()
#6  0x08069999 in boost::detail::shared_count::~shared_count() ()
#7  0x08069952 in boost::shared_ptr<SS::Conf::SSConfNode>::~shared_ptr() ()
#8  0x00124fde in SS::Conf::SSConfManager::createConfFile(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) () from /home/y/lib/libSS_conf.so.1
#9  0x00125e0c in SS::Conf::SSConfManager::createAllConfFiles() () from /home/y/lib/libSS_conf.so.1
#10 0x0012946b in SS::Conf::SSConfManager::initFromDisk(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) () from /home/y/lib/libSS_conf.so.1
#11 0x00129c3b in SS::Conf::SSConfManager::configure(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) () from /home/y/lib/libSS_conf.so.1
#12 0x00156d0c in SS::Init::configure() () from /home/y/lib/libSS_init.so.1
#13 0x0805ac63 in SS::Main::init() ()
#14 0x0807117e in main ()

そして私のプロセスには1つのスレッドしか含まれていません:

(gdb) info thread
* 1 Thread 0xf77a8a40 (LWP 16724)  0x00c54430 in __kernel_vsyscall ()

ヘッダファイルのBOOST_HAS_THREADSの定義を解除してプログラムを再構築すると、すべてうまくいきます

ブースト バージョンは 1.32 です。RHEL4.8 で gcc 3.4.6-11 を使用しています。

4

2 に答える 2

3

質問が何であるかはわかりませんが、これは1.32 ドキュメントの関連部分である可能性があります。

shared_ptrを使用Boost.Configして、実装がスレッドをサポートしているかどうかを検出します。プログラムがシングル スレッドであるが、スレッド セーフのオーバーヘッドを排除するために、プラットフォームがBoost.Config複数のスレッドをサポートするものとして自動検出される場合。#define BOOST_DISABLE_THREADS

したがって、#define BOOST_DISABLE_THREADS未定義の代わりに使用することを検討してくださいBOOST_HAS_THREADS

そして、これは1.33 以降のドキュメントです:

Boost リリース 1.33.0 以降でshared_ptrは、次のプラットフォームでロックフリーの実装を使用します。

  • x86 または x86-64 上の GNU GCC。
  • IA64 上の GNU GCC。
  • PowerPC 上の Metrowerks CodeWarrior。
  • PowerPC 上の GNU GCC;
  • ウィンドウズ。

プログラムがシングル スレッドであり、その既定の構成で shared_ptr を使用した可能性のあるライブラリにリンクしていない場合、プロジェクト全体#defineでマクロBOOST_SP_DISABLE_THREADSを使用して、通常の非アトミック参照カウントの更新に切り替えることができます。

(BOOST_SP_DISABLE_THREADSすべてではありませんが、一部の翻訳単位で定義することは、技術的には 1 つの定義規則および未定義の動作に違反しています。それにもかかわらず、実装は、これらの翻訳単位で非アトミック更新を使用する要求に対応するために最善を尽くします。保証はありません、 けれど。)

マクロを定義BOOST_SP_USE_PTHREADSして、ロックフリーのプラットフォーム固有の実装をオフにし、ジェネリックpthread_mutex_tベースのコードにフォールバックできます。

于 2012-06-08T17:29:19.217 に答える
0

最後に私はその理由を見つけます。私のメインプログラムはブースト 1.32 でビルドされていますが、私の .so ファイルの 1 つはブースト 1.38 でビルドされています。私のプログラムを実行すると、2 つの shared_ptr 実装があり、この問題が発生しました。ブースト 1.32 で so ファイルを再構築した後、プログラムは正常に動作します。

于 2012-06-09T16:07:38.273 に答える