涉及boost :: thread的奇怪崩溃

时间:2014-03-12 21:03:03

标签: c++ multithreading boost

我有一个我正在测试的自定义库。我有单元测试和组件测试。单元测试执行与组件测试相同的所有代码。主要区别在于组件测试必须启动一个单独的线程来运行我的库代码。当它这样做时,我开始看到下面突出显示的崩溃。有些要点需要注意:

  1. 我正在连接agaisnt libboost_system,libboost_thread,pthread,rt等。
  2. 在单元测试中运行相同的调用堆栈而没有问题。
  3. 我检查确保没有* -mt版本的提升线程。我确信我所链接的那个有线程支持。
  4. 在linux主机上不会发生崩溃。只有freebsd。
  5. 我检查堆栈溢出。下面的上下文在第一帧和最后一帧之间使用大约42KB的堆栈空间。我将堆栈大小明确设置为1MB,用于我生成的提升线程。
  6. 我的想法很新鲜。任何建议将不胜感激。

    Program terminated with signal 11, Segmentation fault.
    #0  strcat () at /usr/src/lib/libc/i386/string/strcat.S:50
    50      pushl   %edi            /* save edi */
    (gdb) bt
    #0  strcat () at /usr/src/lib/libc/i386/string/strcat.S:50
    #1  0x2831f603 in tzload (name=0x2834baa0 "UTC", sp=0x283644a0, doextend=1) at /usr/src/lib/libc/stdtime/localtime.c:427
    #2  0x2831fe6f in gmtload (sp=0x0) at /usr/src/lib/libc/stdtime/localtime.c:1203
    #3  0x2831fea6 in gmt_init () at /usr/src/lib/libc/stdtime/localtime.c:1477
    #4  0x28138f60 in _pthread_once (once_control=0x28361560, init_routine=0x2831fe89 <gmt_init at /usr/src/lib/libc/stdtime/localtime.c:1471>)
        at /usr/src/lib/libthr/thread/thr_once.c:87
    #5  0x28323590 in _once (once_control=0x28361560, init_routine=0x2831fe89 <gmt_init at /usr/src/lib/libc/stdtime/localtime.c:1471>)
        at /usr/src/lib/libc/gen/_once_stub.c:62
    #6  0x2831ecb1 in gmtsub (timep=0xbf7fcca4, offset=0, tmp=0xbf7fcc6c) at /usr/src/lib/libc/stdtime/localtime.c:1492
    #7  0x2831ed3c in gmtime_r (timep=0xbf7fcca4, tmp=0xbf7fcc6c) at /usr/src/lib/libc/stdtime/localtime.c:1564
    #8  0x080ab51b in boost::date_time::c_time::gmtime (t=0xbf7fcca4, result=0xbf7fcc6c) at ../../../contrib/opensource/boost/boost/date_time/c_time.hpp:85
    #9  0x080ac4da in boost::asio::time_traits<boost::posix_time::ptime>::now() ()
    #10 0x080a7f99 in expires_from_now (this=0x81181b0) at ../../../contrib/opensource/boost/boost/asio/detail/deadline_timer_service.hpp:155
    #11 expires_from_now (this=0x81181b0) at ../../../contrib/opensource/boost/boost/asio/deadline_timer_service.hpp:124
    #12 expires_from_now (this=0x81181b0) at ../../../contrib/opensource/boost/boost/asio/basic_deadline_timer.hpp:410
    #13 smf::service::Manager::arm_degraded_services_timer (this=0x81181b0) at Manager.cpp:247
    #14 0x080a8747 in smf::service::Manager::defer_degraded_service (this=0x81181b0, service=0x825c140) at Manager.cpp:269
    #15 0x080a8948 in smf::service::Manager::service_signal_handler (this=0x81181b0, error_code=..., signal_number=20) at Manager.cpp:203
    #16 0x080aa267 in operator() (owner=0x8123060, base=0x82567c0) at ../../../contrib/opensource/boost/boost/bind/mem_fn_template.hpp:280
    #17 operator()<boost::_mfi::mf2<void, smf::service::Manager, const boost::system::error_code&, int>, boost::_bi::list2<const boost::system::error_code&, const int&> > (owner=0x8123060, base=0x82567c0) at ../../../contrib/opensource/boost/boost/bind/bind.hpp:392
    #18 operator()<boost::system::error_code, int> (owner=0x8123060, base=0x82567c0) at ../../../contrib/opensource/boost/boost/bind/bind_template.hpp:102
    #19 operator() (owner=0x8123060, base=0x82567c0) at ../../../contrib/opensource/boost/boost/asio/detail/bind_handler.hpp:118
    #20 asio_handler_invoke<boost::asio::detail::binder2<boost::_bi::bind_t<void, boost::_mfi::mf2<void, smf::service::Manager, boost::system::error_code const&, int>, boost::_bi::list3<boost::_bi::value<smf::service::Manager*>, boost::arg<1>, boost::arg<2> > >, boost::system::error_code, int> > (owner=0x8123060, base=0x82567c0)
        at ../../../contrib/opensource/boost/boost/asio/handler_invoke_hook.hpp:64
    #21 invoke<boost::asio::detail::binder2<boost::_bi::bind_t<void, boost::_mfi::mf2<void, smf::service::Manager, boost::system::error_code const&, int>, boost::_bi::list3<boost::_bi::value<smf::service::Manager*>, boost::arg<1>, boost::arg<2> > >, boost::system::error_code, int>, boost::_bi::bind_t<void, boost::_mfi::mf2<void, smf::service::Manager, boost::system::error_code const&, int>, boost::_bi::list3<boost::_bi::value<smf::service::Manager*>, boost::arg<1>, boost::arg<2> > > > (
        owner=0x8123060, base=0x82567c0) at ../../../contrib/opensource/boost/boost/asio/detail/handler_invoke_helpers.hpp:39
    #22 boost::asio::detail::signal_handler<boost::_bi::bind_t<void, boost::_mfi::mf2<void, smf::service::Manager, boost::system::error_code const&, int>, boost::_bi::list3<boost::_bi::value<smf::service::Manager*>, boost::arg<1>, boost::arg<2> > > >::do_complete (owner=0x8123060, base=0x82567c0)
        at ../../../contrib/opensource/boost/boost/asio/detail/signal_handler.hpp:68
    #23 0x080a6243 in boost::asio::detail::task_io_service::run(boost::system::error_code&) ()
    #24 0x080a2b61 in run (this=0x811818c) at ../../../contrib/opensource/boost/boost/asio/impl/io_service.ipp:59
    #25 smf::service::Daemon::run (this=0x811818c) at Daemon.cpp:48
    #26 0x080b69a8 in boost::(anonymous namespace)::thread_proxy (param=0x8124080) at ../src/pthread/thread.cpp:143
    #27 0x281346a5 in thread_start (curthread=0x8136d80) at /usr/src/lib/libthr/thread/thr_create.c:288
    #28 0x00000000 in ?? ()
    

2 个答案:

答案 0 :(得分:0)

从阅读回溯中我发现了一些额外的复杂性,你并没有提到。

看来你正在使用Boost Asio。

在某些时候你处理signal 20 (SIGCHLD)(通常会被忽略)。处理程序为smf::service::Manager::service_signal_handler,后者将调用smf::service::Manager::defer_degraded_service

然后尝试使用expires_from_now上的deadline_timer“武装”一段时间。

这基本上是事情变得糟糕的地方。我查一下

  • 计时器实际上仍然是一个有效的引用(它没有被移动/销毁)
  • UTC实际上是目标平台上的有效时区
  • 正在保护计时器免受并发访问(deadline_timer线程安全)。

    执行此操作的常用方法是将deadline_timer放在 strand (或只有io_service一个帖子上)并发布作业这个strand / service来设置计时器。

答案 1 :(得分:0)

原来这是因为我在程序的其他地方调用了popen,它安装了自己的SIGCHLD处理程序。随之而来的是坏事。