Mutex在boost regex构造函数中断言

The*_*uke 11 c++ regex linux boost initialization

我正在使用boost 1.47 for Arm,使用Code Sourcery C++编译器(4.5.1),从Windows 7开始针对Ubuntu进行交叉编译.

当我们编译调试版本(即启用了断言)时,会触发一个断言:

pthread_mutex_lock.c:62: __pthread_mutex_lock: Assertion 'mutex->__data.__owner == 0' failed.
Run Code Online (Sandbox Code Playgroud)

在发布模式下编译时,不会触发断言并且程序正常工作(据我们所知).

这是在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
Run Code Online (Sandbox Code Playgroud)

我已经确认设置了BOOST_HAS_THREADS,PTHREAD_MUTEX_INITIALIZER也是如此.

我尝试跟随调试器虽然提升但它是模板化的代码并且很难遵循程序集,但我们基本上死在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);
}
Run Code Online (Sandbox Code Playgroud)

模板化的代码是:

// 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;
}
Run Code Online (Sandbox Code Playgroud)

我不确定哪个组件实际上正在使用互斥锁 - 有谁知道?

在调试器中,我可以检索变量的地址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;
Run Code Online (Sandbox Code Playgroud)

我使用这些偏移来检查内存中的数据.这些值没有意义:例如,__data.__lock字段(int)是0xb086b580.所述__count(一个unsigned int)是0x6078af00,和__owner(一个int)是0x6078af00.

这使我认为不会以某种方式初始化此互斥锁.无论是那个还是完全被破坏了,但我倾向于错过初始化,因为当我与调试增强库链接时,没有断言.

现在,我假设无论正在查询的互斥锁是什么全局/静态用于制作正则表达式线程安全,并且它以某种方式未初始化.

  • 有没有人遇到类似的东西?Ubuntu需要一些额外的步骤才能确保互斥初始化吗?
  • 我的实施假设是否正确?
  • 如果它是正确的,有人可以指向我声明这个互斥锁的位置,以及它在何处进行初始化
  • 有关进一步调试步骤的建议吗?我想我可能不得不以某种方式下载源并在那里进行跟踪重建(希望StackOverflow在我到达这一点之前可以帮助我)

Ted*_*ton 1

当像 boost 这样的众所周知的、经过充分测试的库中出现真正奇怪的运行时崩溃时,首先要检查的事情之一是是否存在标头/库配置不匹配。恕我直言,将 _DEBUG 或 NDEBUG 放在标头中,特别是在结构中以影响其二进制布局的方式,是一种反模式。理想情况下,无论我们定义 _DEBUG、DEBUG、Debug、 Debug 、NDEBUG 还是其他任何东西,我们都应该能够使用相同的 .lib (这样我们就可以根据是否想要有调试符号来选择 .lib,而不是根据是否有调试符号来选择 .lib)。匹配标头定义)。不幸的是情况并非总是如此。