我正在为 Arm 使用 boost 1.47,使用 Code Sourcery C++ 编译器 (4.5.1),从针对 Ubuntu 的 Windows 7 进行交叉编译。
当我们编译调试版本(即启用断言)时,触发了一个断言:
pthread_mutex_lock.c:62: __pthread_mutex_lock: Assertion 'mutex->__data.__owner == 0' failed.
在发布模式下编译,断言没有被触发并且程序工作正常(据我们所知)。
这是在 Ubuntu 10.x Arm 板下发生的。
因此,pthread_mutex_lock 似乎认为互斥锁是由与当前线程不同的线程设置的。此时在我的程序中,我们仍然是单线程的,通过在 main 中打印出 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
我已经确认设置了 BOOST_HAS_THREADS 和 PTHREAD_MUTEX_INITIALIZER。
我尝试通过 boost 来跟踪调试器,但它是模板代码,并且很难跟踪程序集,但我们基本上死在 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
an unsigned int) 是 0x6078af00,__owner
(an int) 是 0x6078af00。
这使我认为没有执行此互斥锁的某种初始化。要么是这样,要么是完全损坏,但我倾向于错过初始化,因为当我与调试提升库链接时,没有断言。
现在,我假设正在查询的任何互斥体都是一些全局/静态的,用于使正则表达式线程安全,并且不知何故它没有被初始化。
- 有没有人遇到过类似的事情?Ubuntu 是否需要一些额外的步骤来确保互斥体初始化?
- 我的实现假设是否正确?
- 如果它是正确的,有人可以指出这个互斥锁的声明位置,以及它的初始化发生在哪里
- 关于进一步调试步骤的任何建议?我在想我可能不得不以某种方式下载源代码并在那里进行跟踪重建(希望 StackOverflow 在我到达这一点之前可以帮助我)