私はArmにboost1.47を使用しており、Code Sourcery C ++コンパイラ(4.5.1)を使用して、Ubuntuを対象としたWindows7からのクロスコンパイルを行っています。
デバッグバージョンをコンパイルすると(つまり、アサートが有効になると)、アサートがトリガーされます。
pthread_mutex_lock.c:62: __pthread_mutex_lock: Assertion 'mutex->__data.__owner == 0' failed.
リリースモードでコンパイルすると、アサーションはトリガーされず、プログラムは正常に動作します(私たちが知る限り)。
これはUbuntu10.xArmボードで発生しています。
したがって、pthread_mutex_lockは、ミューテックスが現在のスレッドとは異なるスレッドによって設定されたと見なしているようです。私のプログラムのこの時点では、まだシングルスレッドであり、メインで正規表現コンストラクターが呼び出される直前にpthread_selfを出力することで検証されています。つまり、アサーションに失敗するべきではありませんでした。
以下は、問題を引き起こすコードのスニペットです。
// Set connection server address and port from a URL
bool MyHttpsXmlClient::set_server_url(const std::string& server_url)
{
#ifdef BOOST_HAS_THREADS
cout <<"Boost has threads" << endl;
#else
cout <<"WARNING: boost does not support threads" << endl;
#endif
#ifdef PTHREAD_MUTEX_INITIALIZER
cout << "pthread mutex initializer" << endl;
#endif
{
pthread_t id = pthread_self();
printf("regex: Current threadid: %d\n",id);
}
const boost::regex e("^((http|https)://)?([^:]*)(:([0-9]*))?"); // 2: service, 3: host, 5: port // <-- dies in here
PTHREAD_MUTEX_INITIALIZERと同様に、BOOST_HAS_THREADSが設定されていることを確認しました。
ブーストを介してデバッガーをフォローしようとしましたが、テンプレート化されたコードであり、アセンブリをフォローするのはかなり困難でしたが、基本的にdo_assignで終了します(basic_regex.hppの380行目)
basic_regex& assign(const charT* p1,
const charT* p2,
flag_type f = regex_constants::normal)
{
return do_assign(p1, p2, f);
}
テンプレート化されたコードは次のとおりです。
// out of line members;
// these are the only members that mutate the basic_regex object,
// and are designed to provide the strong exception guarentee
// (in the event of a throw, the state of the object remains unchanged).
//
template <class charT, class traits>
basic_regex<charT, traits>& basic_regex<charT, traits>::do_assign(const charT* p1,
const charT* p2,
flag_type f)
{
shared_ptr<re_detail::basic_regex_implementation<charT, traits> > temp;
if(!m_pimpl.get())
{
temp = shared_ptr<re_detail::basic_regex_implementation<charT, traits> >(new re_detail::basic_regex_implementation<charT, traits>());
}
else
{
temp = shared_ptr<re_detail::basic_regex_implementation<charT, traits> >(new re_detail::basic_regex_implementation<charT, traits>(m_pimpl->m_ptraits));
}
temp->assign(p1, p2, f);
temp.swap(m_pimpl);
return *this;
}
どのコンポーネントが実際にミューテックスを使用しているかわかりません-誰か知っていますか?
デバッガーでは、変数のアドレスを取得してからmutex
()を検査できますmutex->__data.__owner
。コンパイラヘッダーファイルbits/pthreadtypes.hからオフセットを取得しました。これは、次のことを示しています。
/* Data structures for mutex handling. The structure of the attribute
type is not exposed on purpose. */
typedef union
{
struct __pthread_mutex_s
{
int __lock;
unsigned int __count;
int __owner;
/* KIND must stay at this position in the structure to maintain
binary compatibility. */
int __kind;
unsigned int __nusers;
__extension__ union
{
int __spins;
__pthread_slist_t __list;
};
} __data;
char __size[__SIZEOF_PTHREAD_MUTEX_T];
long int __align;
これらのオフセットを使用して、メモリ内のデータを検査しました。値は意味がありませんでした。たとえば、__data.__lock
フィールド(int)は0xb086b580です。(__count
unsigned int)は0x6078af00であり、__owner
(int)は0x6078af00です。
これは、どういうわけかこのミューテックスの初期化が実行されなかったと私に思わせます。それか完全に破損していますが、デバッグブーストライブラリとリンクしたときにアサートがなかったため、初期化を逃す傾向があります。
ここで、照会されているミューテックスは、正規表現をスレッドセーフにするために使用されるグローバル/静的であり、どういうわけか初期化されていないと想定しています。
- 誰かが似たようなものに遭遇したことがありますか?ミューテックスの初期化を確実にするためにUbuntuに必要な追加の手順はありますか?
- 私の実装の仮定は正しいですか?
- それが正しければ、誰かがこのミューテックスが宣言されている場所と、初期化が行われている場所を教えてもらえますか?
- さらなるデバッグ手順に関する提案はありますか?どういうわけかソースをダウンロードして、そこにトレースを入れて再構築する必要があるかもしれないと思っています(この時点に到達する前にStackOverflowが役立つことを願っています)