首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Boost CI中TSAN中的分段故障-需要专家的帮助

Boost CI中TSAN中的分段故障-需要专家的帮助
EN

Stack Overflow用户
提问于 2022-08-15 09:00:52
回答 1查看 205关注 0票数 4

我正在调试Boost.Beast的CI中TSAN报告的分段故障。

我坚信这是一个假阳性,但我不知道要找什么来抑制它。

在我看来,从堆栈跟踪来看,代码被正确地检测了。该代码通过了所有其他测试,包括val研、ubsan等。

我希望某个善良的专家能让我摆脱痛苦。

这是输出:

代码语言:javascript
复制
====== BEGIN OUTPUT ======
beast.http.read
ThreadSanitizer:DEADLYSIGNAL
==132842==ERROR: ThreadSanitizer: SEGV on unknown address 0x7ff5d9cff000 (pc 0x7ff5dceba0d0 bp 0x000000000000 sp 0x7ff5d9c3d910 T132844)
==132842==The signal is caused by a READ memory access.
    #0 __sanitizer::StackDepotBase<__sanitizer::StackDepotNode, 1, 20>::Put(__sanitizer::StackTrace, bool*) <null> (libtsan.so.2+0xba0d0)
    #1 __tsan::CurrentStackId(__tsan::ThreadState*, unsigned long) <null> (libtsan.so.2+0x8c48f)
    #2 __sanitizer::DD::MutexInit(__sanitizer::DDCallback*, __sanitizer::DDMutex*) <null> (libtsan.so.2+0xac534)
    #3 __tsan::DDMutexInit(__tsan::ThreadState*, unsigned long, __tsan::SyncVar*) <null> (libtsan.so.2+0x9a3f8)
    #4 __tsan::MetaMap::GetSync(__tsan::ThreadState*, unsigned long, unsigned long, bool, bool) <null> (libtsan.so.2+0xa85dc)
    #5 __tsan_atomic32_fetch_add <null> (libtsan.so.2+0x783e9)
    #6 __gnu_cxx::__exchange_and_add(int volatile*, int) /usr/include/c++/12/ext/atomicity.h:66 (read+0x4188f8)
    #7 __gnu_cxx::__exchange_and_add_dispatch(int*, int) /usr/include/c++/12/ext/atomicity.h:101 (read+0x4188f8)
    #8 std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release_last_use() /usr/include/c++/12/bits/shared_ptr_base.h:187 (read+0x4188f8)
    #9 std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release() /usr/include/c++/12/bits/shared_ptr_base.h:361 (read+0x40c592)
    #10 std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count() /usr/include/c++/12/bits/shared_ptr_base.h:1071 (read+0x418fee)
    #11 std::__shared_ptr<boost::asio::detail::strand_executor_service::strand_impl, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr() /usr/include/c++/12/bits/shared_ptr_base.h:1524 (read+0x420f83)
    #12 std::shared_ptr<boost::asio::detail::strand_executor_service::strand_impl>::~shared_ptr() /usr/include/c++/12/bits/shared_ptr.h:175 (read+0x420faf)
    #13 boost::asio::detail::strand_executor_service::invoker<boost::asio::io_context::basic_executor_type<std::allocator<void>, 0ul> const, void>::~invoker() <null> (read+0x471f5f)
    #14 boost::asio::detail::executor_op<boost::asio::detail::strand_executor_service::invoker<boost::asio::io_context::basic_executor_type<std::allocator<void>, 0ul> const, void>, boost::asio::detail::recycling_allocator<void, boost::asio::detail::thread_info_base::default_tag>, boost::asio::detail::scheduler_operation>::do_complete(void*, boost::asio::detail::scheduler_operation*, boost::system::error_code const&, unsigned long) <null> (read+0x48b0ac)
    #15 boost::asio::detail::scheduler_operation::complete(void*, boost::system::error_code const&, unsigned long) boost/asio/detail/scheduler_operation.hpp:40 (read+0x4fa38e)
    #16 boost::asio::detail::scheduler::do_run_one(boost::asio::detail::conditionally_enabled_mutex::scoped_lock&, boost::asio::detail::scheduler_thread_info&, boost::system::error_code const&) boost/asio/detail/impl/scheduler.ipp:492 (read+0x4e8835)
    #17 boost::asio::detail::scheduler::run(boost::system::error_code&) boost/asio/detail/impl/scheduler.ipp:210 (read+0x4e74fb)
    #18 boost::asio::io_context::run() boost/asio/impl/io_context.ipp:63 (read+0x4dc122)
    #19 boost::beast::test::enable_yield_to::enable_yield_to(unsigned long)::{lambda()#1}::operator()() const <null> (read+0x412363)
    #20 void std::__invoke_impl<void, boost::beast::test::enable_yield_to::enable_yield_to(unsigned long)::{lambda()#1}>(std::__invoke_other, boost::beast::test::enable_yield_to::enable_yield_to(unsigned long)::{lambda()#1}&&) <null> (read+0x4a1f92)
    #21 std::__invoke_result<boost::beast::test::enable_yield_to::enable_yield_to(unsigned long)::{lambda()#1}>::type std::__invoke<boost::beast::test::enable_yield_to::enable_yield_to(unsigned long)::{lambda()#1}>(boost::beast::test::enable_yield_to::enable_yield_to(unsigned long)::{lambda()#1}&&) <null> (read+0x49f9dc)
    #22 void std::thread::_Invoker<std::tuple<boost::beast::test::enable_yield_to::enable_yield_to(unsigned long)::{lambda()#1}> >::_M_invoke<0ul>(std::_Index_tuple<0ul>) <null> (read+0x49c90a)
    #23 std::thread::_Invoker<std::tuple<boost::beast::test::enable_yield_to::enable_yield_to(unsigned long)::{lambda()#1}> >::operator()() <null> (read+0x49941e)
    #24 std::thread::_State_impl<std::thread::_Invoker<std::tuple<boost::beast::test::enable_yield_to::enable_yield_to(unsigned long)::{lambda()#1}> > >::_M_run() <null> (read+0x494c2a)
    #25 execute_native_thread_routine <null> (libstdc++.so.6+0xdbb72)
    #26 __tsan_thread_start_func <null> (libtsan.so.2+0x393ef)
    #27 start_thread <null> (libc.so.6+0x8ce2c)
    #28 clone3 <null> (libc.so.6+0x1121af)

ThreadSanitizer can not provide additional info.
SUMMARY: ThreadSanitizer: SEGV (/lib64/libtsan.so.2+0xba0d0) in __sanitizer::StackDepotBase<__sanitizer::StackDepotNode, 1, 20>::Put(__sanitizer::StackTrace, bool*)
==132842==ABORTING

正在测试的代码是最新的master分支。

命令行复制:

代码语言:javascript
复制
$ ./b2 toolset=gcc thread-sanitizer=norecover link=static variant=debug libs/beast/test -q -d+2 -j1

我的编译器信息:

代码语言:javascript
复制
$ gcc --version
gcc (GCC) 12.1.1 20220507 (Red Hat 12.1.1-1)
Copyright (C) 2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

我的操作系统是Fedora 36。但我们在Ubuntu上也看到了这种情况。

EN

回答 1

Stack Overflow用户

发布于 2022-08-16 13:47:52

谢谢每一个在这件事上插嘴的人。我得到了传奇的Chris的帮助,他是Asio库的作者。

引用:

线程杀菌剂似乎不能正确地处理线程间迁移的协同线/光纤堆栈。这将被认为是线程清除器中的一个bug,或者可能是对它的特性请求。

问题在于线程清理程序库本身。

在这种情况下,解决方法是重新构造代码,以便光纤的启动在与其进行进展的线程相同的线程上进行。

下面是旧代码(正确但不兼容TSAN):

代码语言:javascript
复制
template<class F0, class... FN>
inline
void
enable_yield_to::
spawn(F0&& f, FN&&... fn)
{
    asio::spawn(ioc_,
        [&](yield_context yield)
        {
            f(yield);
            std::lock_guard<std::mutex> lock{m_};
            if(--running_ == 0)
                cv_.notify_all();
        }
        , boost::coroutines::attributes(2 * 1024 * 1024));
    spawn(fn...);
}

下面是解决方案的代码:

代码语言:javascript
复制
template<class F0, class... FN>
inline
void
enable_yield_to::
spawn(F0&& f, FN&&... fn)
{
    // dispatch of spawn is a workaround for
    // https://github.com/boostorg/beast/issues/2499
    asio::dispatch(ioc_, 
        [&]
        {
            asio::spawn(ioc_,
                [&](yield_context yield)
                {
                    f(yield);
                    std::lock_guard<std::mutex> lock{m_};
                    if(--running_ == 0)
                        cv_.notify_all();
                }
                , boost::coroutines::attributes(2 * 1024 * 1024));
        });
    spawn(fn...);
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73358829

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档