互斥量在boost regex构造函数中声明
我使用Code Sourcery C ++编译器(4.5.1)针对Arm使用boost 1.47,从针对Ubuntu的Windows 7进行交叉编译。
当我们编译调试版本(即断言被启用)时,会触发一个断言:
pthread_mutex_lock.c:62: __pthread_mutex_lock: Assertion 'mutex->__data.__owner == 0' failed.
在释放模式下编译,断言不会被触发,程序也能正常工作(据我们所知)。
这是在Ubuntu 10.x手臂板下发生的。
所以,似乎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: %dn",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
)。 我从编译器头文件位/ 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。
这导致我认为这个互斥体的初始化没有被执行。 无论是它或它完全损坏,但我倾向于错过初始化,因为当我与调试增强库链接时,没有断言。
现在,我假设被查询的任何互斥量是用于使正则表达式线程安全的全局/静态,并且不知何故它没有被初始化。
首先要检查的是,真正真正特有的运行时崩溃出现在像boost这样的众所周知的经过充分测试的库中是否存在头/库配置不匹配。 恕我直言,将_DEBUG或NDEBUG放在标题中,特别是在影响其二进制布局的结构中,是一种反模式。 理想情况下,无论我们是否定义_DEBUG,DEBUG,Debug,Debug,NDEBUG或其他类型,我们都应该能够使用相同的.lib(这样我们就可以根据是否需要调试符号来选择.lib,而不是匹配头部定义)。 不幸的是,情况并非总是如此。
我使用这些偏移来检查内存中的数据。 这些值没有意义:例如, __data.__lock
字段(一个int)是0xb086b580。 __count
(一个无符号> int)是0x6078af00, __owner
(一个int)是0x6078af00。
这听起来像你的代码的不同部分对各种结构应该有多大有不同的看法。 有些事情要检查:
#define
,但是在整个代码库中没有一致地设置? (在Windows上, _SECURE_SCL
对这类错误声名_SECURE_SCL
) #pragma pack
,并忘记在标题末尾取消设置,则之后包含的任何数据结构将具有与程序中其他位置不同的布局。