You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

boost::regex_match线程安全疑问:ThreadSanitizer竞态条件是否为误报?

ThreadSanitizer检测boost::regex_match竞态条件的误报分析

问题背景

  • ThreadSanitizer检测到boost::regex_match存在竞态条件,但认为这是误报。
  • 调用栈中未发现依赖BOOST_HAS_THREADS的同步原语。
  • 所有输入参数均位于各自线程的栈内存中,不存在共享数据访问的情况。

ThreadSanitizer警告日志

==================
WARNING: ThreadSanitizer: data race (pid=1893)
  Write of size 4 at 0x007e19fa8ff0 by thread T36:
    #0 boost::re_detail_106700::saved_state::saved_state(unsigned int) include/boost/regex/v4/perl_matcher_non_recursive.hpp:59 
    #1 boost::re_detail_106700::perl_matcher<char const*, std::allocator<boost::sub_match<char const*> >, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::push_recursion_stopper() include/boost/regex/v4/perl_matcher_non_recursive.hpp:288
    #2 boost::re_detail_106700::perl_matcher<char const*, std::allocator<boost::sub_match<char const*> >, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::match_all_states() include/boost/regex/v4/perl_matcher_non_recursive.hpp:202
    #3 boost::re_detail_106700::perl_matcher<char const*, std::allocator<boost::sub_match<char const*> >, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::match_prefix() include/boost/regex/v4/perl_matcher_common.hpp:336
    #4 boost::re_detail_106700::perl_matcher<char const*, std::allocator<boost::sub_match<char const*> >, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::match_imp() include/boost/regex/v4/perl_matcher_common.hpp:220
    #5 boost::re_detail_106700::perl_matcher<char const*, std::allocator<boost::sub_match<char const*> >, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::match() include/boost/regex/v4/perl_matcher_common.hpp:193
    #6 bool boost::regex_match<char const*, std::allocator<boost::sub_match<char const*> >, char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >(char const*, char const*, boost::match_results<char const*, std::allocator<boost::sub_match<char const*> > >&, boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > > const&, boost::regex_constants::_match_flags) include/boost/regex/v4/regex_match.hpp:50
    #7 bool boost::regex_match<char, std::allocator<boost::sub_match<char const*> >, boost::regex_traits<char, boost::cpp_regex_traits<char> > >(char const*, boost::match_results<char const*, std::allocator<boost::sub_match<char const*> > >&, boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > > const&, boost::regex_constants::_match_flags) /var/lib/jenkins/workspace/nightly-jnd-navigation__tsd-nav-rsi-viwi-dev/system/ext-boost-dev/dist/17-89ad-bc06/usr/include/boost/regex/v4/regex_match.hpp:73 (tsd.nav.mainapp.mib3+0x3dd0610)
<...>

  Previous write of size 4 at 0x007e19fa8ff0 by thread T105:
    [failed to restore the stack]

  Location is heap block of size 4096 at 0x007e19fa8000 allocated by thread T105:
    #0 operator new(unsigned long) <null> (libtsan.so.0+0x79f54)
    #1 boost::re_detail_106700::save_state_init::save_state_init(boost::re_detail_106700::saved_state**, boost::re_detail_106700::saved_state**) include/boost/regex/v4/perl_matcher_non_recursive.hpp:107
    #2 boost::re_detail_106700::perl_matcher<char const*, std::allocator<boost::sub_match<char const*> >, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::match_imp() include/boost/regex/v4/perl_matcher_common.hpp:202
    #3 boost::re_detail_106700::perl_matcher<char const*, std::allocator<boost::sub_match<char const*> >, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::match() include/boost/regex/v4/perl_matcher_common.hpp:193
    #4 bool boost::regex_match<char const*, std::allocator<boost::sub_match<char const*> >, char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >(char const*, char const*, boost::match_results<char const*, std::allocator<boost::sub_match<char const*> > >&, boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > > const&, boost::regex_constants::_match_flags) include/boost/regex/v4/regex_match.hpp:50
    #5 bool boost::regex_match<char, std::allocator<boost::sub_match<char const*> >, boost::regex_traits<char, boost::cpp_regex_traits<char> > >(char const*, boost::match_results<char const*, std::allocator<boost::sub_match<char const*> > >&, boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > > const&, boost::regex_constants::_match_flags) include/boost/regex/v4/regex_match.hpp:73

误报分析

  1. 内存归属判断:竞态涉及的堆内存由线程T105分配,属于save_state_init为perl_matcher实例创建的内部状态块。每个线程调用regex_match时会生成独立的perl_matcher实例,理论上不会跨线程共享该内存块。
  2. 栈回溯问题:线程T105的栈回溯未能完整恢复,可能是TSAN的栈解析误差,导致无法确认该内存块是否已被正确释放并复用,进而误判为共享访问。
  3. 无共享数据佐证:所有输入参数均为线程栈私有,调用栈中也未发现缺失同步原语的情况,符合线程安全的调用场景。

综上,该警告大概率是ThreadSanitizer的误报,可能源于内存分配器的内存复用机制被错误识别为竞态访问。

内容的提问来源于stack exchange,提问作者Desperado17

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 11:31:01