[Bug libstdc++/126399] [15/16/17 Regression] __gthread_trigger() is missing hidden visibility on FreeBSD/Solaris

andy at omnios dot org gcc-bugzilla@gcc.gnu.org
Tue Sep 1 11:28:50 GMT 2026


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126399

andy at omnios dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |andy at omnios dot org

--- Comment #3 from andy at omnios dot org ---
Confirming this on x86_64-pc-solaris2.11 (illumos, OmniOS r151059) with
GCC 15.2.0.

We first noticed that when LLVM/clang began to abort on every invocation
after changing to build against gcc15 rather than gcc14.

  terminate called after throwing an instance of 'std::system_error'
    what():  Unknown error
  ...
  13 libstdc++.so.6.0.34  std::__throw_system_error(int) + 75
  14 libLLVM.so.19.1      llvm::initializeIRTranslatorPass(...) + 283
  ...
  17 clang-19             llvm::InitializeAllTargets() + 14

That is the first std::call_once executed inside libLLVM.so. The
library's __gthread_active_p() binds __gthread_trigger to the
executable's exported copy, so the executable's hidden flag is set,
libLLVM's own stays -1, is clamped to 0, and __gthread_once() returns
-1 from then on (hence strerror(-1) = "Unknown error").

The silent version is worse than the abort - __gthread_mutex_lock()
consults the same flag, so std::mutex locks become no-ops in the
affected object.

Here is our portable reproducer with two shared libraries, which does
not depend on the executable exporting its globals (Solaris ld does;
GNU ld does not), so it should reproduce on FreeBSD with the same headers:

  $ cat liba.cc
  #include <mutex>
  static std::once_flag f;
  extern "C" void a_once() { std::call_once(f, []{}); }

  $ cat libb.cc
  #include <mutex>
  #include <cstdio>
  static std::once_flag f;
  extern "C" void b_once() { std::call_once(f, []{ std::puts("libb once ran");
}); }

  $ cat main.cc
  #include <cstdio>
  extern "C" void a_once();
  extern "C" void b_once();
  int main() { b_once(); std::puts("ok"); return 0; }

  $ g++ -std=c++17 -shared -fPIC liba.cc -o liba.so
  $ g++ -std=c++17 -shared -fPIC libb.cc -o libb.so
  $ g++ -std=c++17 main.cc -o main -L. -la -lb -Wl,-R$PWD
  $ ./main
  terminate called after throwing an instance of 'std::system_error'
    what():  Unknown error
  (exit status 134)

OmniOS is shipping the equivalent of attachment 65126 in its GCC 15
since 2026-09-01 and has rebuilt the affected packages with it.

As nothing seems to have reached gcc-patches yet, we are happy to
submit the patch for trunk and the 15/16 branches with

  libgcc/ChangeLog:

        PR libstdc++/126399
        * gthr-posix.h (__gthread_trigger): Move into the hidden
        visibility region alongside __gthread_active.

unless the reporter would prefer to.


More information about the Gcc-bugs mailing list