#1291 Static data duplication and unitialized usage / link failures
Metadata
| Property | Value |
|---|---|
| Reported by | Steffen Müthing (steffen.muething@iwr.uni-heidelberg.de) |
| Reported at | Apr 29, 2013 19:36 |
| Type | Bug Report |
| Version | 2.2 |
| Operating System | Unspecified / All |
| Last edited by | Steffen Müthing (steffen.muething@iwr.uni-heidelberg.de) |
| Last edited at | Oct 9, 2013 05:04 |
| Closed by | Steffen Müthing (steffen.muething@iwr.uni-heidelberg.de) |
| Closed at | Oct 9, 2013 05:04 |
| Closed in version | Unknown |
| Resolution | Fixed |
| Comment | Fixed in dune-common e628beb and dune-geometry 228271c |
Description
I have been working around a problem with dune-geometry for the better part of a year now, where my programs would randomly crash somewhere in the reference element setup code.
I always thought that this was a problem limited to my (admittedly rather quirky) OS X setup, but last week Jurgis Pods told me about similar problems he was encountering.
The issue is really technical and I honestly don't completely understand how it is triggered: dune-geometry contains quite a lot of singleton template classes, which are all realized approximately like this:
template class A { A(); public: static const A& instance() { static A a; return a; } };
In every compilation unit that contains a call to A::instance(), the compiler instantiates the method and generates a weak symbol (as well as weak symbols for the static variable a and its guard variable). Those weak symbols are later merged by the linker to satisfy the ODR requirements of C++. That part is easy enough. Unfortunately, this doesn't work when multiple libraries contain definitions of instance(), as the compiler will sometimes fail to correctly deduce the symbol type of instance(), a or its guard variable. In some cases, they will not be marked as weak, while in other cases they become private (invisible from outside the library), which wreaks havoc and creates a horrible mix of initialized and un-initialized versions of the same static variable within the process (on my machine) or an outright linker failure due to ODR violation (Jurgis).
After some googling I found the following web page about symbol visibility and libraries:
http://gcc.gnu.org/wiki/Visibility
That page recommends explicitly marking exported symbols with attribute((visibility("default"))) or an appropriate wrapper macro. Doing so actually fixes the problem, so I suggest adding DUNE_EXPORT and DUNE_PRIVATE macros to dune-common and annotating the involved methods in dune-geometry (see attached patches).
One patch adds a new header visibility.hh with the required macros to dune-common, the other marks all affected methods in dune-geometry.