Дима Рубинштейн (dimrub) wrote in gotchas,
Дима Рубинштейн

Recursive initialization of a local static variable with gcc4.3

Problem: a process (that, among other things, contains some singletons implemented by using static local variables) gets stuck on startup.

Analysis: initially, the singletons were implemented via statics defined in the global scope. This was dangerous, because the order of initialization of globals is undefined among the different compilation units, and in fact, the compilation unit that contained the definition of that static HAD to be specified last in the list of libraries, so that it's globals be initialized first. This assumption is hard to enforce, and its future existence is not guaranteed (not to mention possible other problems of interaction with other such globals).

The solution proposed, for example, by Meyers, is to move the global statics into a local scope. Such statics are being inited the first time the function which contains them is being called. This makes sense for a singleton, whose instance is always accessed through the instance() method.

In this particular instance, however, the aforementioned change caused the process to get stuck during the startup. It was always stuck in something called __cxa_guard_acquire(). This function, it appears, is part of the C++ ABI (Application Binary Interface), and is something g++ uses to ensure some degree of thread safety for the local statics initialization. Apparently, this guard is non-reentrant. There was a code flow during the initialization of the aforementioned static, that caused the same static to be used, thus causing reentry to the guard. The problem was solved by breaking this cyclic dependence.
Tags: c++, linux
  • Post a new comment


    Anonymous comments are disabled in this journal

    default userpic

    Your IP address will be recorded