[Bug libstdc++/98108] New: Broken Schwarz counter for iostreams initialization

2020-12-02 Thread i.hamsa at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98108

Bug ID: 98108
   Summary: Broken Schwarz counter for iostreams initialization
   Product: gcc
   Version: 10.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: i.hamsa at gmail dot com
  Target Milestone: ---

Iostreams initialization doesn't work in multithreaded environments.

To reproduce one needs two source files:

// file1.cc

  #include   

  void threadfunc();  

  struct StaticThread {
  std::thread t;  
  StaticThread() : t(threadfunc) {}
  ~StaticThread() { t.join(); }
  };  

  static StaticThread thread1, thread2;

//file2.cc

  #include   

  void threadfunc() {
  std::cout << "Printing\n";
  }  

  int main() {}

//compile
g++ -pthread file1.cc file2.cc

It is important that  is NOT included in file1.cc.

The resulting executable always crashes on my machine (Gentoo Linux). Add
 to file1.cc, the crash disappears. Change the order of source files
in the command line, the crash disappears.

---

The culprit is ios_base::Init::_S_refcount. Basically it is an atomic nifty
counter. The problem is, the nifty counter idiom doesn't work with
multithreading. Making it atomic achieves absolutely nothing. If we have two or
more threads that can enter Init::Init() at the same time, one should proceed
and the rest must WAIT. It is the same thing as initialization of a static
object in a block scope, and should be interlocked in exactly the same way.

[Bug libstdc++/98108] Broken Schwarz counter for iostreams initialization

2020-12-03 Thread i.hamsa at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98108

--- Comment #2 from i.hamsa at gmail dot com ---
The standard streams are not user defined objects. They need to be initialized
before any user code touches them, before `main`, before everything, no matter
what. This is exactly the purpose of the "nifty counter". It works perfectly
well in single-threaded environments.

The problem is that libstdc++ implementation of it purports to be thread-safe.
It isn't.

[Bug libstdc++/98108] Broken Schwarz counter for iostreams initialization

2020-12-16 Thread i.hamsa at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98108

--- Comment #8 from i.hamsa at gmail dot com ---
After re-reading the relevant parts of the standard, I have convinced myself
that the program is indeed not required to work unless  is included,
even in a single-threaded version. Even though the standard encourages
implementations to initialise the standard iostreams objects earlier than
required, it is not mandatory.