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

Ubuntu20.04下ANTLR4 C++ demo运行触发__gthread错误求助

问题描述
  • 运行环境:VirtualBox 虚拟机内 Ubuntu 20.04 系统,使用 g++ 9.4.0 编译器完成 ANTLR4 C++ 运行时编译
  • 故障现象:编译 ANTLR4 自带 demo 过程无报错,运行生成的 ELF 文件时在 Lexer 初始化阶段崩溃,初步判断为 __gthread 未正常启动
  • 已做排查:检查项目 CMakeLists.txt 未发现 gthread 包的链接配置,系统为全新安装的 Ubuntu 20.04

gdb 调试输出如下:

Breakpoint 1, main () at /home/zhao/Downloads/antlr4/runtime/Cpp/demo/Linux/main.cpp:22
22  int main(int , const char **) {
(gdb) n
23    ANTLRInputStream input(u8"🍴 = 🍐 + \"😎\";(((x * π))) * µ + ∰; a + (x * (y ? 0 : 1) + z);");
(gdb) n
24    TLexer lexer(&input);
(gdb) s
antlrcpptest::TLexer::TLexer (this=0x7fffffffdb20, input=0x7fffffffda50) at /home/zhao/Downloads/antlr4/runtime/Cpp/demo/generated/TLexer.cpp:171
171 TLexer::TLexer(CharStream *input) : Lexer(input) {
(gdb) n
172   TLexer::initialize();
(gdb) s
antlrcpptest::TLexer::initialize () at /home/zhao/Downloads/antlr4/runtime/Cpp/demo/generated/TLexer.cpp:272
272 void TLexer::initialize() {
(gdb) s
273   std::call_once(tlexerLexerOnceFlag, tlexerLexerInitialize);
(gdb) s
std::call_once<void (&)()> (__once=..., __f=@0x7fffffffda00: {void (void)} 0x7fffffffda00) at /usr/include/c++/9/mutex:666
666     call_once(once_flag& __once, _Callable&& __f, _Args&&... __args)
(gdb) s
670       auto __callable = [&] {
(gdb) 
675       __once_callable = std::__addressof(__callable); // NOLINT: PR 82481
(gdb) 
std::__addressof<std::call_once<void (&)()>(std::once_flag&, void (&)())::{lambda()#1}>(void (&)()) (__r=...) at /usr/include/c++/9/bits/move.h:47
47      __addressof(_Tp& __r) _GLIBCXX_NOEXCEPT
(gdb) 
48      { return __builtin_addressof(__r); }
(gdb) 
std::call_once<void (&)()> (__once=..., __f=@0x55555556b4c3: {void (void)} 0x55555556b4c3 <(anonymous namespace)::tlexerLexerInitialize()>)
    at /usr/include/c++/9/mutex:675
675       __once_callable = std::__addressof(__callable); // NOLINT: PR 82481
(gdb) 
676       __once_call = []{ (*(decltype(__callable)*)__once_callable)(); };
(gdb) 
std::call_once<void (&)()>(std::once_flag&, void (&)())::{lambda()#2}::operator void (*)()() const (this=0x7fffffffda00) at /usr/include/c++/9/mutex:676
676       __once_call = []{ (*(decltype(__callable)*)__once_callable)(); };
(gdb) 
std::call_once<void (&)()> (__once=..., __f=@0x55555556b4c3: {void (void)} 0x55555556b4c3 <(anonymous namespace)::tlexerLexerInitialize()>)
    at /usr/include/c++/9/mutex:683
683       int __e = __gthread_once(&__once._M_once, &__once_proxy);
(gdb) 
__gthread_once (__once=0x5555556e32bc <(anonymous namespace)::tlexerLexerOnceFlag>, __func=0x7ffff7eabc20 <__once_proxy>)
    at /usr/include/x86_64-linux-gnu/c++/9/bits/gthr-default.h:699
699   if (__gthread_active_p ())
(gdb) s
__gthread_active_p () at /usr/include/x86_64-linux-gnu/c++/9/bits/gthr-default.h:252
252   return __gthread_active_ptr != 0;
(gdb) display __gthread_active_ptr
1: __gthread_active_ptr = (void * const) 0x0
(gdb) n
253 }
1: __gthread_active_ptr = (void * const) 0x0
(gdb) n
__gthread_once (__once=0x5555556e32bc <(anonymous namespace)::tlexerLexerOnceFlag>, __func=0x7ffff7eabc20 <__once_proxy>)
    at /usr/include/x86_64-linux-gnu/c++/9/bits/gthr-default.h:699
699   if (__gthread_active_p ())
1: __gthread_active_ptr = (void * const) 0x0
(gdb) n
702     return -1;
1: __gthread_active_ptr = (void * const) 0x0
(gdb) n
703 }
1: __gthread_active_ptr = (void * const) 0x0
(gdb) n
std::call_once<void (&)()> (__once=..., __f=@0x55555556b4c3: {void (void)} 0x55555556b4c3 <(anonymous namespace)::tlexerLexerInitialize()>)
    at /usr/include/c++/9/mutex:690
690       if (__e)
1: __gthread_active_ptr = (void * const) 0x0
(gdb) n
691     __throw_system_error(__e);
故障原因

__gthread_active_ptr 为空不是系统依赖缺失导致的,全新安装的 Ubuntu 20.04 只要安装了 build-essential 和 g++ 就已经包含全部线程相关依赖,不需要额外安装软件包。
该报错本质是编译链接阶段没有正确关联 POSIX 线程库,导致 libstdc++ 的 gthread 兼容层找不到 pthread 实现,std::call_once 执行时直接返回错误触发异常。

解决步骤
  1. 修改 demo 目录下的 CMakeLists.txt,添加线程库依赖配置:
# 查找系统线程库
find_package(Threads REQUIRED)

# 链接到目标可执行文件,注意把 antlr4-demo 替换成实际的编译目标名
target_link_libraries(antlr4-demo PRIVATE 
    antlr4_static
    Threads::Threads
)

不要手动硬编码 -lpthread 链接参数,使用 CMake 官方提供的 Threads::Threads 目标可以自动适配不同平台的线程实现,避免兼容问题。

  1. 清理旧的编译缓存,重新编译:
# 进入 ANTLR4 C++ 运行时的 build 目录,或自行创建的 demo 编译目录
rm -rf *
cmake ..
make -j$(nproc)
  1. 重新运行生成的可执行文件即可正常执行,不会再触发 gthread 相关崩溃。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 12:31:10